diff options
author | rpj <rpj> | 2001-07-08 16:44:06 +0000 |
---|---|---|
committer | rpj <rpj> | 2001-07-08 16:44:06 +0000 |
commit | f58aab44e671bb39b8afb29804a9ca94c238c523 (patch) | |
tree | d1bac0558d5146c6468f8f421f22762f382c6c6e /tests | |
parent | 704925281289e0f937eab045bd327b4275b2e03a (diff) |
Barriers fixed and tested more extensively.
* barrier.c: Fix several bugs in all routines. Now passes
tests/barrier5.c which is fairly rigorous. There is still
a non-optimal work-around for a race condition between
the barrier breeched event signal and event wait. Basically
the last (signalling) thread to hit the barrier yields
to allow any other threads, which may have lost the race,
to complete.
tests/ChangeLog:
* barrier3.c: Fixed.
* barrier4.c: Fixed.
* barrier5.c: New; proves that all threads in the group
reaching the barrier wait and then resume together. Repeats
the test using groups of 1 to 16 threads. Each group of
threads must negotiate a large number of barriers (10000).
* spin4.c: Fixed.
* test.h (error_string): Modified the success (0) value.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ChangeLog | 11 | ||||
-rw-r--r-- | tests/GNUmakefile | 3 | ||||
-rw-r--r-- | tests/Makefile | 3 | ||||
-rw-r--r-- | tests/barrier3.c | 2 | ||||
-rw-r--r-- | tests/barrier4.c | 12 | ||||
-rw-r--r-- | tests/barrier5.c | 93 | ||||
-rw-r--r-- | tests/spin4.c | 2 | ||||
-rw-r--r-- | tests/test.h | 2 |
8 files changed, 122 insertions, 6 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog index 1c5d766..144454a 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,14 @@ +2001-07-09 Ross Johnson <rpj@setup1.ise.canberra.edu.au> + + * barrier3.c: Fixed. + * barrier4.c: Fixed. + * barrier5.c: New; proves that all threads in the group + reaching the barrier wait and then resume together. Repeats the test + using groups of 1 to 16 threads. Each group of threads must negotiate + a large number of barriers (10000). + * spin4.c: Fixed. + * test.h (error_string): Modified the success (0) value. + 2001-07-07 Ross Johnson <rpj@setup1.ise.canberra.edu.au> * spin3.c: Changed test and fixed. diff --git a/tests/GNUmakefile b/tests/GNUmakefile index f005664..d62e45c 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -49,7 +49,7 @@ TESTS = loadfree \ cleanup0 cleanup1 cleanup2 cleanup3 \ priority1 priority2 inherit1 \ spin1 spin2 spin3 spin4 \ - barrier1 barrier2 barrier3 barrier4 \ + barrier1 barrier2 barrier3 barrier4 barrier5 \ exception1 exception2 exception3 BENCHTESTS = \ @@ -96,6 +96,7 @@ barrier1.pass: barrier2.pass: barrier1.pass barrier3.pass: barrier2.pass barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass cancel1.pass: create1.pass cancel2.pass: cancel1.pass cancel2_1.pass: cancel2.pass diff --git a/tests/Makefile b/tests/Makefile index f3a4f91..dba30d3 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -58,7 +58,7 @@ PASSES= loadfree.pass \ cleanup0.pass cleanup1.pass cleanup2.pass cleanup3.pass \
priority1.pass priority2.pass inherit1.pass \
spin1.pass spin2.pass spin3.pass spin4.pass \
- barrier1.pass barrier2.pass barrier3.pass barrier4.pass \
+ barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \
exception1.pass exception2.pass exception3.pass
BENCHRESULTS = \
@@ -151,6 +151,7 @@ barrier1.pass: barrier2.pass: barrier1.pass
barrier3.pass: barrier2.pass
barrier4.pass: barrier3.pass
+barrier5.pass: barrier4.pass
cancel1.pass: create1.pass
cancel2.pass: cancel1.pass
cancel3.pass: context1.pass
diff --git a/tests/barrier3.c b/tests/barrier3.c index 97f6dc2..1fea5a1 100644 --- a/tests/barrier3.c +++ b/tests/barrier3.c @@ -28,7 +28,7 @@ main() assert(pthread_create(&t, NULL, func, NULL) == 0); - assert(pthread_join(t, (void *) &result) == 0); + assert(pthread_join(t, (void **) &result) == 0); assert(result == PTHREAD_BARRIER_SERIAL_THREAD); diff --git a/tests/barrier4.c b/tests/barrier4.c index 8f33e85..dd40b79 100644 --- a/tests/barrier4.c +++ b/tests/barrier4.c @@ -23,14 +23,24 @@ func(void * arg) int result = pthread_barrier_wait(&barrier); assert(pthread_mutex_lock(&mx) == 0); + +// printf("Barrier wait returned %d [%d]\n", result, WAIT_FAILED); +// fflush(stdout); + if (result == PTHREAD_BARRIER_SERIAL_THREAD) { serialThreadCount++; } - else + else if (0 == result) { otherThreadCount++; } + else + { + printf("Barrier wait failed: error = %s\n", error_string[result]); + fflush(stdout); + return NULL; + } assert(pthread_mutex_unlock(&mx) == 0); return NULL; diff --git a/tests/barrier5.c b/tests/barrier5.c new file mode 100644 index 0000000..6576b05 --- /dev/null +++ b/tests/barrier5.c @@ -0,0 +1,93 @@ +/* + * barrier5.c + * + * Declare a single barrier object, set up a sequence of + * barrier points to prove lockstepness, and then destroy it. + * + */ + +#include "test.h" + +enum { + NUMTHREADS = 16, + ITERATIONS = 10000 +}; + +pthread_barrier_t barrier = NULL; +pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; + +int barrierReleases[ITERATIONS + 1]; + +void * +func(void * barrierHeight) +{ + int i; + int result; + + for (i = 1; i < ITERATIONS; i++) + { + result = pthread_barrier_wait(&barrier); + + assert(pthread_mutex_lock(&mx) == 0); + barrierReleases[i]++; + assert(pthread_mutex_unlock(&mx) == 0); + /* + * Confirm the correct number of releases from the previous + * barrier. We can't do the current barrier yet because there may + * still be threads waking up. + */ + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + assert(pthread_mutex_lock(&mx) == 0); +//printf("Releases bucket %d = %d\n", i - 1, barrierReleases[i - 1]); +//fflush(stdout); + assert(barrierReleases[i - 1] == (int) barrierHeight); + barrierReleases[i + 1] = 0; + assert(pthread_mutex_unlock(&mx) == 0); + } + else if (result != 0) + { + printf("Barrier failed: result = %s\n", error_string[result]); + fflush(stdout); + return NULL; + } + } + + return NULL; +} + +int +main() +{ + int i, j; + pthread_t t[NUMTHREADS + 1]; + + for (j = 1; j <= NUMTHREADS; j++) + { + printf("Barrier height = %d\n", j); + + barrierReleases[0] = j; + barrierReleases[1] = 0; + + assert(pthread_barrier_init(&barrier, NULL, j) == 0); + + for (i = 1; i <= j; i++) + { + assert(pthread_create(&t[i], NULL, func, (void *) j) == 0); + } + + for (i = 1; i <= j; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + assert(barrierReleases[ITERATIONS - 1] == j); + assert(barrierReleases[ITERATIONS] == 0); + + assert(pthread_barrier_destroy(&barrier) == 0); + } + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} diff --git a/tests/spin4.c b/tests/spin4.c index 5f04a27..8f73008 100644 --- a/tests/spin4.c +++ b/tests/spin4.c @@ -59,7 +59,7 @@ main() assert(pthread_spin_unlock(&lock) == 0); - assert(pthread_join(t, (void *) &result) == 0); + assert(pthread_join(t, (void **) &result) == 0); assert(result > 1000); assert(pthread_spin_destroy(&lock) == 0); diff --git a/tests/test.h b/tests/test.h index 018b215..c5b565d 100644 --- a/tests/test.h +++ b/tests/test.h @@ -13,7 +13,7 @@ #include <stdio.h> char * error_string[] = { - "ZERO", + "ZERO_or_EOK", "EPERM", "ENOFILE_or_ENOENT", "ESRCH", |