pth_barrier_race.c revision ed07e00d438c74b7a23c01bfffde77e3968305e4
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Test program that triggers a race between pthread_barrier_wait() and 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * pthread_barrier_destroy(): proper synchronization is missing between 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the pthread_barrier_wait() and the pthread_barrier_destroy() calls. This 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * test program is based on the example that was posted on February 5, 2009 by 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Christoph Bartoschek on the valgrind-users mailing list. Redistribution of 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the source code below is permitted under the GPLv2 license. 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * See also http://article.gmane.org/gmane.comp.debugging.valgrind/8945/match=pthread_barrier_wait 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define _GNU_SOURCE 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_barrier_t* barrier; 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* thread(void* arg) 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_barrier_wait(barrier); 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main() 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t tid; 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown barrier = (pthread_barrier_t *) malloc(sizeof(*barrier)); 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_barrier_init(barrier, NULL, 2); 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create(&tid, NULL, thread, NULL); 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_barrier_wait(barrier); 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The sleep() call below ensures that the pthread_barrier_destroy() call 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * happens after the created thread has returned from pthread_barrier_wait(). 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleep(1); 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_barrier_destroy(barrier); 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free(barrier); 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(tid, NULL); 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 49