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.
This commit is contained in:
Andrew Johnson
2010-10-29 11:58:44 -05:00
parent c84c3d49ad
commit 1e6464cdc4
2 changed files with 55 additions and 3 deletions

View File

@@ -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();
}

View File

@@ -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);