diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2011-11-09 18:15:33 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-11-16 10:07:41 -0600 |
commit | 6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6 (patch) | |
tree | 9538afbe255b4f4d1e9bf9cd878ad4e89f43844c /src/usr/targeting/test/targetingtest.H | |
parent | 4d9344f1025ee77e24e88249dd3e32f3d4c9a3ba (diff) | |
download | talos-hostboot-6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6.tar.gz talos-hostboot-6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6.zip |
Support host boot mutex attributes
- Prevented mutex attributes from being copied in target APIs
- Added target APIs to get/tryGet mutex attribute references
- Added testcases to verify mutex attributes
- Added mutex attribute type to XML definition
- Added test mutex attribute to system target XML definition
- Modified attribute compiler to support mutex attributes and restrictions
- Replaced 100000 cycle loop in synctest.H with nanosleep for 10 CTX switches
- Added context switch time macros to time.h
- Removed context switch time macros from taskwaittest.H
and renamed existing macro calls
- Removed context switch time macros from synctest.H
and renamed existing macro calls
Change-Id: I93fecfa75e00e509fa442e4dd5c9e3fd67866e98
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/491
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/targeting/test/targetingtest.H')
-rw-r--r-- | src/usr/targeting/test/targetingtest.H | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H index a2a25ab34..c6d732cee 100644 --- a/src/usr/targeting/test/targetingtest.H +++ b/src/usr/targeting/test/targetingtest.H @@ -44,6 +44,9 @@ #include <fapiAttributeIds.H> #include <fapiAttributeService.H> #include <errl/errlmanager.H> +#include <sys/sync.h> +#include <sys/task.h> +#include <sys/time.h> // This component #include <targeting/attributes.H> @@ -54,6 +57,31 @@ #include <targeting/predicates/predicatectm.H> #include <targeting/predicates/predicatepostfixexpr.H> +/** + * @brief Struct to hold pointers to a mutex / protected value + */ +struct MutexTestData_t +{ + mutex_t* pMutex; // Pointer to mutex + volatile uint32_t* pVar; // Pointer to value protected by mutex +}; + +/** + * @brief Function which attempts to write a protected variable + * + * @param[in] i_pData Pointer to mutex pointer/value pointer structure + * + * @return N/A + */ +void funcTestMutex(void* i_pData) +{ + MutexTestData_t* l_pData = static_cast<MutexTestData_t*>(i_pData); + mutex_lock(l_pData->pMutex); + *(l_pData->pVar) = 1; + mutex_unlock(l_pData->pMutex); + task_end(); +} + class TargetingTestSuite: public CxxTest::TestSuite { public: @@ -1336,6 +1364,102 @@ class TargetingTestSuite: public CxxTest::TestSuite TS_TRACE(EXIT_MRK "testCentaurs" ); } + + void testHbMutexAttr() + { + TS_TRACE(ENTER_MRK "testHbMutexAttr" ); + + using namespace TARGETING; + using namespace fapi; + + do { + + // Get a reference to the target service + TargetService& l_targetService = targetService(); + + // Get the system target containing the test mutex + TARGETING::Target* l_pTarget = NULL; + (void) l_targetService.getTopLevelTarget(l_pTarget); + if (l_pTarget == NULL) + { + TS_FAIL("Top level target handle is NULL"); + break; + } + + // Get the mutex attribute (actually a mutex_t* which points to + // a mutex) + HB_MUTEX_TEST_LOCK_ATTR l_pLock + = l_pTarget->getHbMutexAttr<TARGETING::ATTR_HB_MUTEX_TEST_LOCK>(); + + // Test: Verify the value pointed to by the mutex_t* is zero + if ( (*reinterpret_cast<uint64_t*>(l_pLock)) != 0) + { + TS_FAIL("Mutex attribute must be initialized to zero, but got %ld", + *reinterpret_cast<uint64_t*>(l_pLock)); + break; + } + + // Try to get the attribute, and ensure it's the same + HB_MUTEX_TEST_LOCK_ATTR l_pLockTry = NULL; + if(l_pTarget->tryGetHbMutexAttr<TARGETING::ATTR_HB_MUTEX_TEST_LOCK> + (l_pLockTry)) + { + if(l_pLockTry != l_pLock) + { + TS_FAIL("Mutex attributes should match, but dont. " + "l_pLockTry = %ld, l_pLock = %ld",l_pLockTry, + l_pLock); + break; + } + } + else + { + TS_FAIL("Mutex attribute tryGet failed, even though it exists"); + break; + } + + // Create a structue holding pointers to the mutex and a protected value + volatile uint32_t l_var = 0; + (void)mutex_lock(l_pLock); + MutexTestData_t l_mutexTestData = { l_pLock, &l_var }; + + // Spawn off a function which tries to write the protected value to + // something unexpected. If the mutex is working, the for loop will + // always poll the expected value. + task_create(funcTestMutex, static_cast<void*>(&l_mutexTestData)); + + // Guarantee the child process runs and blocks on the mutex prior to + // modifying the protected value. isync to ensure the processor doesn't + // speculatively perform the comparison prior to the sleep completing + nanosleep(0,TEN_CTX_SWITCHES_NS); isync(); + + if(l_var != 0) + { + TS_FAIL("Protected value must be 0, was %d instead",l_var); + break; + } + + // Now unlock the mutex, allowing the other thread to overwrite the + // protected value; which should happen within 100,000 reads of the + // var. This will confirm the other thread was actively trying to + // write the controlled value + (void)mutex_unlock(l_pLock); + + // Guarantee the child process acquires the mutex and modifies the + // protected value; isync to ensure the processor doesn't speculatively + // perform the comparison prior to the sleep completing + nanosleep(0,TEN_CTX_SWITCHES_NS); isync(); + + if(l_var != 1) + { + TS_FAIL("Protected value must now be 1, was %d instead",l_var); + break; + } + + } while(0); + + TS_TRACE(EXIT_MRK "testHbMutexAttr"); + } }; #endif // End __TESTTARGETING_H |