[SourceForge Project page] [DUT home] [Getting and Using DUT] [Why Use DUT] [Plans for DUT]
As originally written, DUT was completely unaware of concurrency, which is not to say that you couldn't use it to test code that was going to run concurrently. You could detect even race conditions with code like:
Which has no internal trouble (because there is no chance of DUT test macros running concurrently), and will report race conditions fairly regularly.#include "dut.h" #include <pthead.h> #define NITER 100000 int count = 0; void* plus(void *a){ int i, local; for (i=0; i<NITER; i++){ local = count; local++; count+=local; }; }; void* minus(void *a){ int i, local; for (i=0; i<NITER; i++){ local = count; local--; count+=local; }; }; int main(int argc, char** argv){ DUT_TEST_FILE_HEADER; pthread_t th1, th2; pthread_create(&th1,NULL,&plus,NULL); pthread_create(&th2,NULL,&minus,NULL); pthread_join(th1,NULL); pthread_join(th2,NULL); DUT_TESTEQ_WARN("Race condition",count,0,%i,DUT_INT); DUT_TEST_FILE_FOOTER; };
But is was not safe to run tests concurrently. DUT uses global storage to keep track of the description of the current test, how many test have been completed, how many tests have generated warnings, and so on. A race condition between tests could result in erroneous reporting of what failure occurred where...
For version 0.8.3 a simple (and optional) locking mechanism based on POSIX semaphores was installed. There is no fundamental reason other kinds of semaphores could not be used.
You activate the locking mechanism
by #define
ing _DUT_THREAD_SAFE_
, which
simply brackets all the test macros with a (un)locking calls on
the semaphore DUT_UPDATE_SEM
. This renders it safe
to use DUT test macros in multi-threaded code as long as your
test code (CVAL
and TVAL
) does not
block on other semaphore controlled resources, which could
result in deadlocks.
Since you're writing concurrent code, I assume that you are familiar with the risks and the standard solutions. Good luck.