From 0c5edba986eb543bc94ecb3514c40ca151dafc61 Mon Sep 17 00:00:00 2001 From: Matt Raybuck Date: Wed, 24 Oct 2018 07:54:39 -0500 Subject: Added support for recursive mutexes There was only support for non-recursive mutexes. This commit adds support for recursive mutexes and a new API for using them. Change-Id: I664c181af1633b05b8b2da6b1ff21b93a37cec28 RTC: 196793 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67938 Reviewed-by: Nicholas E. Bofferding Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Reviewed-by: Ilya Smirnov Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell --- src/usr/testcore/lib/makefile | 4 +-- src/usr/testcore/lib/synctest.H | 78 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) (limited to 'src/usr/testcore/lib') diff --git a/src/usr/testcore/lib/makefile b/src/usr/testcore/lib/makefile index a688b2a8f..ce80dc0df 100644 --- a/src/usr/testcore/lib/makefile +++ b/src/usr/testcore/lib/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2011,2016 +# Contributors Listed Below - COPYRIGHT 2011,2018 # [+] International Business Machines Corp. # # @@ -28,7 +28,7 @@ MODULE = testsyslib #@TODO-RTC:151185-Turn enable all test cases #TESTS = *.H TESTS = stltest.H - +TESTS += synctest.H SUBDIRS += runtime.d diff --git a/src/usr/testcore/lib/synctest.H b/src/usr/testcore/lib/synctest.H index c75e97db9..2662f020d 100644 --- a/src/usr/testcore/lib/synctest.H +++ b/src/usr/testcore/lib/synctest.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2014 */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -41,6 +43,49 @@ class SyncTest: public CxxTest::TestSuite { public: + void testRecursiveMutex(void) + { + int l_status = TASK_STATUS_EXITED_CLEAN; + // Note: These test cases are considered to have passed if no + // deadlocks occur. + // Case 1: Single thread locks recursive mutex three times in a row. + { + recursive_mutex_init(&mutex); + + l_status = TASK_STATUS_EXITED_CLEAN; + tid_t l_task1 = task_create(entry_func, this); + + if ((l_task1 != task_wait_tid(l_task1, &l_status, nullptr)) || + (l_status == TASK_STATUS_EXITED_CLEAN)) + { + TS_INFO("Thread ended."); + } + } + + // Case 2: One thread grabs recursive mutex and another attempts to + // grab it (hangs) and then the first thread grabs it again + // without issue. + { + recursive_mutex_init(&mutex); + + l_status = TASK_STATUS_EXITED_CLEAN; + tid_t l_task1 = task_create(entry_func, this); + tid_t l_task2 = task_create(entry_func, this); + + if ((l_task2 != task_wait_tid(l_task2, &l_status, nullptr)) || + (l_status == TASK_STATUS_EXITED_CLEAN)) + { + TS_INFO("Thread ended."); + } + + if ((l_task1 != task_wait_tid(l_task1, &l_status, nullptr)) || + (l_status == TASK_STATUS_EXITED_CLEAN)) + { + TS_INFO("Thread ended."); + } + + } + } void testMutex() { @@ -142,10 +187,6 @@ class SyncTest: public CxxTest::TestSuite // test is success if it completes w/o hang } - - - - private: enum @@ -162,6 +203,33 @@ class SyncTest: public CxxTest::TestSuite size_t counter; + static void* entry_func(void* i_p) + { + SyncTest* my = (SyncTest*) i_p; + mutex_t* myMutex = &(my->mutex); + + // Call the recursive function. + recursive_func(myMutex, 2); + + return nullptr; + } + + static void recursive_func(mutex_t* mutex, int val) + { + TS_INFO("Attempting to enter Critical Section."); + recursive_mutex_lock(mutex); + + TS_INFO("Accessing Critical Section."); + nanosleep(0, TEN_CTX_SWITCHES_NS); + + if (val > 0) + { + recursive_func(mutex, val-1); + } + + TS_INFO("Exiting Critical Section."); + recursive_mutex_unlock(mutex); + } static void* func1(void * i_p) { -- cgit v1.2.1