diff options
author | Michel Lespinasse <walken@google.com> | 2009-11-23 09:28:40 -0800 |
---|---|---|
committer | Darren Hart <dvhltc@us.ibm.com> | 2009-11-23 09:59:33 -0800 |
commit | e6f351a97480f4e6ed17d379006e654a7c25af23 (patch) | |
tree | b3033e64220d309468c5050d9e5e973e33a0b710 | |
parent | 06ec805e9339f31345f62c978f842a1bca860a5b (diff) | |
download | futextest-e6f351a97480f4e6ed17d379006e654a7c25af23.tar.gz |
Check for pthread_create errors and move barrier logic into harness
If thread creation fails then join with existing threads and exit.
Moved the before/after barrier logic into the test harness rather
than the futex_[set]wait_test functions.
Signed-off-by: Michel Lespinasse <walken@google.com>
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
-rw-r--r-- | performance/futex_wait.c | 13 | ||||
-rw-r--r-- | performance/harness.h | 35 |
2 files changed, 31 insertions, 17 deletions
diff --git a/performance/futex_wait.c b/performance/futex_wait.c index 88ce2f2..bcbca77 100644 --- a/performance/futex_wait.c +++ b/performance/futex_wait.c @@ -35,17 +35,12 @@ static inline void futex_cmpxchg_unlock(futex_t *futex) } } -static void * futex_wait_test(void * dummy) +static void futex_wait_test(futex_t *futex, int loops) { - struct locktest_shared * shared = dummy; - int i = shared->loops; - barrier_sync(&shared->barrier_before); - while (i--) { - futex_wait_lock(&shared->futex); - futex_cmpxchg_unlock(&shared->futex); + while (loops--) { + futex_wait_lock(futex); + futex_cmpxchg_unlock(futex); } - barrier_sync(&shared->barrier_after); - return NULL; } int main (void) diff --git a/performance/harness.h b/performance/harness.h index 849209d..7b23bdc 100644 --- a/performance/harness.h +++ b/performance/harness.h @@ -15,6 +15,7 @@ struct thread_barrier { struct locktest_shared { struct thread_barrier barrier_before; struct thread_barrier barrier_after; + void (* locktest_function)(futex_t *ptr, int loops); int loops; futex_t futex; }; @@ -27,13 +28,14 @@ static void barrier_init(struct thread_barrier *barrier, int threads) } /* Called by worker threads to synchronize with main thread */ -static void barrier_sync(struct thread_barrier *barrier) +static int barrier_sync(struct thread_barrier *barrier) { futex_dec(&barrier->threads); if (barrier->threads == 0) futex_wake(&barrier->threads, 1, FUTEX_PRIVATE_FLAG); while (barrier->unblock == 0) futex_wait(&barrier->unblock, 0, NULL, FUTEX_PRIVATE_FLAG); + return barrier->unblock; } /* Called by main thread to wait for all workers to reach sync point */ @@ -46,14 +48,24 @@ static void barrier_wait(struct thread_barrier *barrier) } /* Called by main thread to unblock worker threads from their sync point */ -static void barrier_unblock(struct thread_barrier *barrier) +static void barrier_unblock(struct thread_barrier *barrier, int value) { - barrier->unblock = 1; + barrier->unblock = value; futex_wake(&barrier->unblock, INT_MAX, FUTEX_PRIVATE_FLAG); } +static void * locktest_thread(void * dummy) +{ + struct locktest_shared * shared = dummy; + if (barrier_sync(&shared->barrier_before) > 0) { + shared->locktest_function(&shared->futex, shared->loops); + barrier_sync(&shared->barrier_after); + } + return NULL; +} -static void locktest(void * thread_function(void *), int iterations) +static void locktest(void locktest_function(futex_t * ptr, int loops), + int iterations) { int threads[] = { 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 24, 32, 64, 128, 256, 512, 1024, 0 }; @@ -70,15 +82,22 @@ static void locktest(void * thread_function(void *), int iterations) barrier_init(&shared.barrier_before, num_threads); barrier_init(&shared.barrier_after, num_threads); + shared.locktest_function = locktest_function; shared.loops = iterations / num_threads; shared.futex = 0; for (i = 0; i < num_threads; i++) - pthread_create(thread + i, NULL, thread_function, - &shared); + if (pthread_create(thread + i, NULL, locktest_thread, + &shared)) { + /* Could not create thread; abort */ + barrier_unblock(&shared.barrier_before, -1); + while (--i >= 0) + pthread_join(thread[i], NULL); + return; + } barrier_wait(&shared.barrier_before); before = times(&tms_before); - barrier_unblock(&shared.barrier_before); + barrier_unblock(&shared.barrier_before, 1); barrier_wait(&shared.barrier_after); after = times(&tms_after); wall = after - before; @@ -91,7 +110,7 @@ static void locktest(void * thread_function(void *), int iterations) (num_threads * shared.loops) / (wall * tick * 1000), user * tick, system * tick, wall * tick, wall ? (user + system) * 1. / wall : 1.); - barrier_unblock(&shared.barrier_after); + barrier_unblock(&shared.barrier_after, 1); for (i = 0; i < num_threads; i++) pthread_join(thread[i], NULL); } |