* for more details.
*/
-#include <sched.h>
-#include <pthread.h>
-
#include "test_suite.h"
+#include <sched.h>
+
+#include <threading/thread.h>
#include <threading/mutex.h>
+#include <threading/condvar.h>
/*******************************************************************************
* recursive mutex test
#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);
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++)
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