pth_barrier2.vgtest \
pth_barrier3.stderr.exp \
pth_barrier3.vgtest \
+ pth_barrier_race.stderr.exp \
+ pth_barrier_race.vgtest \
pth_barrier_reinit.stderr.exp \
pth_barrier_reinit.vgtest \
pth_broadcast.stderr.exp \
endif
if HAVE_PTHREAD_BARRIER
-check_PROGRAMS += matinv pth_barrier pth_barrier_reinit
+check_PROGRAMS += matinv pth_barrier pth_barrier_race pth_barrier_reinit
endif
if HAVE_PTHREAD_SPINLOCK
--- /dev/null
+/*
+ * Test program that triggers a race between pthread_barrier_wait() and
+ * pthread_barrier_destroy(): proper synchronization is missing between
+ * the pthread_barrier_wait() and the pthread_barrier_destroy() calls. This
+ * test program is based on the example that was posted on February 5, 2009 by
+ * Christoph Bartoschek on the valgrind-users mailing list. Redistribution of
+ * the source code below is permitted under the GPLv2 license.
+ *
+ * See also http://article.gmane.org/gmane.comp.debugging.valgrind/8945/match=pthread_barrier_wait
+ */
+
+
+#include <pthread.h>
+#include <stdlib.h>
+
+
+static pthread_barrier_t* barrier;
+
+
+static void* thread(void* arg)
+{
+ pthread_barrier_wait(barrier);
+ return NULL;
+}
+
+int main()
+{
+ pthread_t tid;
+
+ barrier = (pthread_barrier_t *) malloc(sizeof(*barrier));
+ pthread_barrier_init(barrier, NULL, 2);
+
+ pthread_create(&tid, NULL, thread, NULL);
+
+ pthread_barrier_wait(barrier);
+ /*
+ * The sleep() call below ensures that the pthread_barrier_destroy() call
+ * happens after the created thread has returned from pthread_barrier_wait().
+ */
+ sleep(1);
+ pthread_barrier_destroy(barrier);
+ free(barrier);
+
+ pthread_join(tid, NULL);
+ return 0;
+}
--- /dev/null
+
+Destruction of barrier not synchronized with barrier wait call: barrier 0x........
+ at 0x........: pthread_barrier_destroy (drd_pthread_intercepts.c:?)
+ by 0x........: main (pth_barrier_race.c:?)
+Conflicting wait call by thread 0/2:
+ at 0x........: pthread_barrier_wait (drd_pthread_intercepts.c:?)
+ by 0x........: thread (pth_barrier_race.c:?)
+ by 0x........: vgDrd_thread_wrapper (drd_pthread_intercepts.c:?)
+ by 0x........: (within libpthread-?.?.so)
+ by 0x........: clone (in /...libc...)
+barrier 0x........ was first observed at:
+ at 0x........: pthread_barrier_init (drd_pthread_intercepts.c:?)
+ by 0x........: main (pth_barrier_race.c:?)
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)