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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user