diff options
Diffstat (limited to 'helgrind/tests/bar_bad.c')
-rw-r--r-- | helgrind/tests/bar_bad.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/helgrind/tests/bar_bad.c b/helgrind/tests/bar_bad.c new file mode 100644 index 0000000..dd6079c --- /dev/null +++ b/helgrind/tests/bar_bad.c @@ -0,0 +1,89 @@ + +/* This program checks that Helgrind reports the five degenerate + uses of the barrier functions shown. */ +#define _GNU_SOURCE +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <unistd.h> +#include <string.h> + +void* child1 ( void* arg ) +{ + pthread_barrier_wait( (pthread_barrier_t*)arg ); + return NULL; +} + +int main ( void ) +{ + pthread_barrier_t *bar1, *bar2, *bar3, *bar4, *bar5; + pthread_t thr1, thr2; + int r; + + /* possibly set up a watchdog timer thread here. */ + + + + + + + + + + + + /* initialise a barrier with a zero count */ + fprintf(stderr, "\ninitialise a barrier with zero count\n"); + bar1 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar1, NULL, 0); + + /* initialise a barrier twice */ + fprintf(stderr, "\ninitialise a barrier twice\n"); + bar2 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar2, NULL, 1); + pthread_barrier_init(bar2, NULL, 1); + + /* initialise a barrier which has threads waiting on it. + This isn't too simple. */ + fprintf(stderr, "\ninitialise a barrier which has threads waiting on it\n"); + bar3 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar3, NULL, 2); + /* create a thread, whose only purpose is to block on the barrier */ + pthread_create(&thr1, NULL, child1, (void*)bar3); + /* guarantee that it gets there first */ + sleep(1); + /* and now reinitialise */ + pthread_barrier_init(bar3, NULL, 3); + + /* destroy a barrier that has threads waiting at it */ + fprintf(stderr, "\ndestroy a barrier that has waiting threads\n"); + /* once again, create a thread, whose only purpose is to block. */ + bar4 = malloc(sizeof(pthread_barrier_t)); + pthread_barrier_init(bar4, NULL, 2); + /* create a thread, whose only purpose is to block on the barrier */ + pthread_create(&thr2, NULL, child1, (void*)bar4); + /* guarantee that it gets there first */ + sleep(1); + /* and now destroy */ + pthread_barrier_destroy(bar4); + + /* destroy a barrier that was never initialised. This is a bit + tricky, in that we have to fill the barrier with bytes which + ensure that the pthread_barrier_destroy call doesn't hang for + some reason. Zero-fill seems to work ok on amd64-linux (glibc + 2.8). */ + fprintf(stderr, "\ndestroy a barrier that was never initialised\n"); + bar5 = malloc(sizeof(pthread_barrier_t)); + assert(bar5); + memset(bar5, 0, sizeof(*bar5)); + pthread_barrier_destroy(bar5); + + /* now we need to clean up the mess .. */ + r= pthread_cancel(thr1); assert(!r); + r= pthread_cancel(thr2); assert(!r); + + free(bar1); free(bar2); free(bar3); free(bar4); free(bar5); + + return 0; +} |