From 1e6464cdc403eb145d045eb6191317de77c47a53 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 29 Oct 2010 11:58:44 -0500 Subject: [PATCH] libCom/test: Various improvements. Made epicsThreadOnceTest more deterministic, replacing an epicsThreadSleep() with epicsEventMustWait(), and added a diagnostic message before running the thread recurse test. Eric added a series of checks to epicsEventTest.cpp which ensure that epicsEventSignal() only wakes one waiting thread. --- src/libCom/test/epicsEventTest.cpp | 49 ++++++++++++++++++++++++++- src/libCom/test/epicsThreadOnceTest.c | 9 +++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/libCom/test/epicsEventTest.cpp b/src/libCom/test/epicsEventTest.cpp index 85938aa35..31da6208b 100644 --- a/src/libCom/test/epicsEventTest.cpp +++ b/src/libCom/test/epicsEventTest.cpp @@ -106,6 +106,52 @@ static void producer(void *arg) testOk(errors == 0, "%s: errors = %d", name, errors); } +#define SLEEPERCOUNT 3 +struct wakeInfo { + epicsEventId event; + epicsMutexId countMutex; + int count; +}; +static void sleeper(void *arg) +{ + struct wakeInfo *wp = (struct wakeInfo *)arg; + epicsEventMustWait(wp->event); + epicsMutexLock(wp->countMutex); + wp->count++; + epicsMutexUnlock(wp->countMutex); +} +static void eventWakeupTest(void) +{ + struct wakeInfo wakeInfo, *wp = &wakeInfo; + int i, c; + + wp->event = epicsEventMustCreate(epicsEventEmpty); + wp->countMutex = epicsMutexMustCreate(); + wp->count = 0; + for (i = 0 ; i < SLEEPERCOUNT ; i++) + epicsThreadCreate("Sleeper", + epicsThreadPriorityScanHigh, + epicsThreadGetStackSize(epicsThreadStackSmall), + sleeper, + wp); + epicsThreadSleep(0.5); + epicsMutexLock(wp->countMutex); + c = wp->count; + epicsMutexUnlock(wp->countMutex); + testOk(c == 0, "all threads still sleeping"); + for (i = 1 ; i <= SLEEPERCOUNT ; i++) { + epicsEventSignal(wp->event); + epicsThreadSleep(0.5); + epicsMutexLock(wp->countMutex); + c = wp->count; + epicsMutexUnlock(wp->countMutex); + testOk(c == i, "%d thread%s awakened, expected %d", c, c == 1 ? "" : "s", i); + } + epicsEventDestroy(wp->event); + epicsMutexDestroy(wp->countMutex); +} + + } // extern "C" static double eventWaitMeasureDelayError( const epicsEventId &id, const double & delay ) @@ -144,7 +190,7 @@ MAIN(epicsEventTest) epicsEventId event; int status; - testPlan(11); + testPlan(12+SLEEPERCOUNT); event = epicsEventMustCreate(epicsEventEmpty); @@ -200,6 +246,7 @@ MAIN(epicsEventTest) epicsThreadSleep(1.0); eventWaitTest(); + eventWakeupTest(); return testDone(); } diff --git a/src/libCom/test/epicsThreadOnceTest.c b/src/libCom/test/epicsThreadOnceTest.c index 4f0dcd586..5e9088442 100644 --- a/src/libCom/test/epicsThreadOnceTest.c +++ b/src/libCom/test/epicsThreadOnceTest.c @@ -22,6 +22,7 @@ epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; epicsThreadOnceId twiceFlag = EPICS_THREAD_ONCE_INIT; epicsMutexId lock; epicsEventId go; +epicsEventId done; int runCount = 0; int initCount = 0; @@ -49,6 +50,8 @@ void onceThread(void *ctx) epicsMutexMustLock(lock); doneCount++; + if (doneCount == runCount) + epicsEventSignal(done); epicsMutexUnlock(lock); } @@ -79,6 +82,7 @@ MAIN(epicsThreadOnceTest) testPlan(3 + NUM_ONCE_THREADS); go = epicsEventMustCreate(epicsEventEmpty); + done = epicsEventMustCreate(epicsEventEmpty); lock = epicsMutexMustCreate(); for (i = 0; i < NUM_ONCE_THREADS; i++) { @@ -92,12 +96,13 @@ MAIN(epicsThreadOnceTest) epicsThreadSleep(0.1); testOk(runCount == NUM_ONCE_THREADS, "runCount = %d", runCount); - epicsEventSignal(go); - epicsThreadSleep(0.1); + epicsEventSignal(go); /* Use epicsEventBroadcast(go) when available */ + epicsEventMustWait(done); testOk(doneCount == NUM_ONCE_THREADS, "doneCount = %d", doneCount); testDiag("init was run by %s", initBy); + testDiag("Expecting thread recurse to suspend:"); tid = epicsThreadCreate("recurse", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackSmall), recurseThread, 0);