From: Martin Willi Date: Mon, 21 Oct 2013 09:38:29 +0000 (+0200) Subject: unit-tests: Use a home-brew thread barrier to remove pthread dependency X-Git-Tag: 5.1.2dr1~33^2~36 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=f23fd4c59be0046418de059fe3b08de6f8ae4cf1;p=thirdparty%2Fstrongswan.git unit-tests: Use a home-brew thread barrier to remove pthread dependency --- diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c index 0c768b3e2a..c75d6de21f 100644 --- a/src/libstrongswan/tests/suites/test_threading.c +++ b/src/libstrongswan/tests/suites/test_threading.c @@ -14,12 +14,13 @@ * for more details. */ -#include -#include - #include "test_suite.h" +#include + +#include #include +#include /******************************************************************************* * recursive mutex test @@ -27,31 +28,100 @@ #define THREADS 20 -static mutex_t *mutex; +/** + * Thread barrier data + */ +typedef struct { + mutex_t *mutex; + condvar_t *cond; + int count; + int current; + bool active; +} barrier_t; + +/** + * Create a thread barrier for count threads + */ +static barrier_t* barrier_create(int count) +{ + barrier_t *this; -static pthread_barrier_t mutex_barrier; + INIT(this, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .cond = condvar_create(CONDVAR_TYPE_DEFAULT), + .count = count, + ); + + return this; +} + +/** + * Destroy a thread barrier + */ +static void barrier_destroy(barrier_t *this) +{ + this->mutex->destroy(this->mutex); + this->cond->destroy(this->cond); + free(this); +} -static int mutex_locked = 0; +/** + * Wait to have configured number of threads in barrier + */ +static bool barrier_wait(barrier_t *this) +{ + bool winner = FALSE; + + this->mutex->lock(this->mutex); + if (!this->active) + { /* first, reset */ + this->active = TRUE; + this->current = 0; + } + + this->current++; + while (this->current < this->count) + { + this->cond->wait(this->cond, this->mutex); + } + if (this->active) + { /* first, win */ + winner = TRUE; + this->active = FALSE; + } + this->mutex->unlock(this->mutex); + this->cond->broadcast(this->cond); + sched_yield(); + + return winner; +} + +/** + * Barrier for some tests + */ +static barrier_t *barrier; static void *mutex_run(void *data) { + mutex_t *mutex = (mutex_t*)data; + static int locked = 0; int i; /* wait for all threads before getting in action */ - pthread_barrier_wait(&mutex_barrier); + barrier_wait(barrier); for (i = 0; i < 100; i++) { mutex->lock(mutex); mutex->lock(mutex); mutex->lock(mutex); - mutex_locked++; + locked++; sched_yield(); - if (mutex_locked > 1) + if (locked > 1) { fail("two threads locked the mutex concurrently"); } - mutex_locked--; + locked--; mutex->unlock(mutex); mutex->unlock(mutex); mutex->unlock(mutex); @@ -61,9 +131,11 @@ static void *mutex_run(void *data) START_TEST(test_mutex) { - pthread_t threads[THREADS]; + thread_t *threads[THREADS]; + mutex_t *mutex; int i; + barrier = barrier_create(THREADS); mutex = mutex_create(MUTEX_TYPE_RECURSIVE); for (i = 0; i < 10; i++) @@ -80,18 +152,17 @@ START_TEST(test_mutex) mutex->unlock(mutex); } - pthread_barrier_init(&mutex_barrier, NULL, THREADS); for (i = 0; i < THREADS; i++) { - pthread_create(&threads[i], NULL, mutex_run, NULL); + threads[i] = thread_create(mutex_run, mutex); } for (i = 0; i < THREADS; i++) { - pthread_join(threads[i], NULL); + threads[i]->join(threads[i]); } - pthread_barrier_destroy(&mutex_barrier); mutex->destroy(mutex); + barrier_destroy(barrier); } END_TEST