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/targeting/common/xmltohb/xmltohb.pl | 16 +++++- src/usr/testcore/lib/makefile | 4 +- src/usr/testcore/lib/synctest.H | 78 +++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 9 deletions(-) (limited to 'src/usr') diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index c3f8c76f0..e92bf598e 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -4449,6 +4449,17 @@ sub unhexify { return $val; } +################################################################################ +# Pack mutex +################################################################################ + +sub packMutex { + my $length = 24; + my $binaryData .= pack ("C".$length); + + return $binaryData; +} + ################################################################################ # Pack 8 byte value into a buffer using configured endianness ################################################################################ @@ -4868,7 +4879,7 @@ sub simpleTypeProperties { $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt =>\&pack4byte}; $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt =>\&pack8byte}; $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , default => \&defaultEnum , alignment => 1, specialPolicies =>\&null, packfmt => "packEnumeration"}; - $typesHoH{"hbmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "mutex_t*" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 8, specialPolicies =>\&enforceHbMutex, packfmt =>\&pack8byte}; + $typesHoH{"hbmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "mutex_t*" , bytes => 24, bits => 192, default => \&defaultZero , alignment => 8, specialPolicies =>\&enforceHbMutex, packfmt =>\&packMutex}; $typesHoH{"Target_t"} = { supportsArray => 0, canBeHex => 1, complexTypeSupport => 0, typeName => "TARGETING::Target*" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 8, specialPolicies =>\&null, packfmt =>\&pack8byte}; $typesHoH{"fspmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "util::Mutex*" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 8, specialPolicies =>\&enforceFspMutex, packfmt =>\&pack8byte}; @@ -6367,7 +6378,8 @@ sub generateTargetingImage { #skip the present target next; } -# print Dumper($allAttributes); + + #print Dumper($allAttributes); # Update hash with any per-instance overrides, but only if that # attribute has already been defined 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