From c4f6f3ee887c0fa89c4ed5c311410363f6d61cb4 Mon Sep 17 00:00:00 2001 From: Doug Gilbert Date: Thu, 12 Jan 2012 10:32:19 -0600 Subject: Conditional Variable support Change-Id: Ib715b3a4e775ef183244e8769c6560a85ac19104 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/612 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/usr/testcore/lib/synctest.H | 139 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to 'src/usr/testcore/lib/synctest.H') diff --git a/src/usr/testcore/lib/synctest.H b/src/usr/testcore/lib/synctest.H index e1de74843..a5d15b3f2 100644 --- a/src/usr/testcore/lib/synctest.H +++ b/src/usr/testcore/lib/synctest.H @@ -32,8 +32,10 @@ #include #include #include +#include #include +#include class SyncTest: public CxxTest::TestSuite { @@ -80,10 +82,79 @@ class SyncTest: public CxxTest::TestSuite barrier_destroy(&barrier); } + void testConditionVariable() + { + + mutex_init(&mutex); + sync_cond_init(&cond_var); + + counter = 0; + + barrier_init(&barrier,4); + + TASK_INFO t1(this,1); + TASK_INFO t2(this,2); + TASK_INFO t3(this,3); + + task_create(watch_counter, &t1); + task_create(increment, &t2); + task_create(increment, &t3); + + barrier_wait(&barrier); + TS_TRACE("Conditional Variable test final count = %ld",counter); + barrier_destroy(&barrier); + sync_cond_destroy(&cond_var); + mutex_destroy(&mutex); + // test is success if it completes w/o hang + } + + void testConditionVariableBroadcast() + { + mutex_init(&mutex); + sync_cond_init(&cond_var); + + counter = 0; + + barrier_init(&barrier,5); + + TASK_INFO t1(this,4); + TASK_INFO t2(this,5); + TASK_INFO t3(this,6); + TASK_INFO t4(this,7); + + task_create(watch_counter, &t1); + task_create(watch_counter, &t2); + task_create(increment1, &t3); + task_create(increment1, &t4); + + barrier_wait(&barrier); + TS_TRACE("Conditional Variable test final count = %ld",counter); + barrier_destroy(&barrier); + sync_cond_destroy(&cond_var); + mutex_destroy(&mutex); + // test is success if it completes w/o hang + } + + + + + private: + enum + { + TO_COUNT = 10, + COUNT_SIGNAL = 13 + }; + + typedef std::pair TASK_INFO; + mutex_t mutex; barrier_t barrier; + sync_cond_t cond_var; + + size_t counter; + static void func1(void * i_p) { @@ -127,6 +198,74 @@ class SyncTest: public CxxTest::TestSuite task_end(); } + static void watch_counter(void * i_p) + { + TASK_INFO * info = (TASK_INFO *) i_p; + SyncTest * my = info->first; + TS_TRACE("CONDVAR task %ld. Start watching counter",info->second); + mutex_lock(&(my->mutex)); + while(my->counter < COUNT_SIGNAL) + { + sync_cond_wait(&(my->cond_var),&(my->mutex)); + TS_TRACE("CONDVAR task %ld. Condition signal received", + info->second); + my->counter += 100; + TS_TRACE("CONDVAR task %ld. Counter = %ld", + info->second,my->counter); + } + mutex_unlock(&(my->mutex)); + barrier_wait(&(my->barrier)); + } + + + static void increment(void * i_p) + { + TASK_INFO * info = (TASK_INFO *) i_p; + SyncTest * my = info->first; + TS_TRACE("CONDVAR task %ld. start Increment counter",info->second); + for(size_t i = 0; i < TO_COUNT; ++i) + { + mutex_lock(&(my->mutex)); + ++(my->counter); + + if(my->counter == COUNT_SIGNAL) + { + sync_cond_signal(&(my->cond_var)); + TS_TRACE("CONDVAR task %ld. INCR counter = %ld Threshold" + " reached",info->second,my->counter); + } + TS_TRACE("CONDVAR task %ld INCR counter = %ld Unlocking mutex", + info->second, my->counter); + mutex_unlock(&(my->mutex)); + nanosleep(0,TEN_CTX_SWITCHES_NS); + } + barrier_wait(&(my->barrier)); + } + + static void increment1(void * i_p) + { + TASK_INFO * info = (TASK_INFO *) i_p; + SyncTest * my = info->first; + TS_TRACE("CONDVAR task %ld. start Increment counter",info->second); + for(size_t i = 0; i < TO_COUNT; ++i) + { + mutex_lock(&(my->mutex)); + ++(my->counter); + + if(my->counter == COUNT_SIGNAL) + { + sync_cond_broadcast(&(my->cond_var)); + TS_TRACE("CONDVAR task %ld. INCR counter = %ld Threshold" + " reached",info->second,my->counter); + } + TS_TRACE("CONDVAR task %ld INCR counter = %ld Unlocking mutex", + info->second, my->counter); + mutex_unlock(&(my->mutex)); + nanosleep(0,TEN_CTX_SWITCHES_NS); + } + barrier_wait(&(my->barrier)); + } + }; #endif -- cgit v1.2.1