15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/*
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * Test program that triggers a race between pthread_barrier_wait() and
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * pthread_barrier_destroy(): proper synchronization is missing between
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * the pthread_barrier_wait() and the pthread_barrier_destroy() calls. This
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * test program is based on the example that was posted on February 5, 2009 by
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * Christoph Bartoschek on the valgrind-users mailing list. Redistribution of
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * the source code below is permitted under the GPLv2 license.
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer *
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer * See also http://article.gmane.org/gmane.comp.debugging.valgrind/8945/match=pthread_barrier_wait
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer */
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define _GNU_SOURCE
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <pthread.h>
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <stdlib.h>
177573098b83e780d1c5bea13b384b610d8f155676Steve Naroff#include <unistd.h>
18a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerstatic pthread_barrier_t* barrier;
20d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor
219caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
228ffb159441e923322bef6b5dee1aaf24c738d75eTed Kremenekstatic void* thread(void* arg)
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
24525204a7ca5c3c0aac8166d8f27abb988a84c850Anton Korobeynikov  pthread_barrier_wait(barrier);
258189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  return NULL;
266e340496341a4704be0ede9c1ff4f8eacea7ee2cChris Lattner}
277573098b83e780d1c5bea13b384b610d8f155676Steve Naroff
287573098b83e780d1c5bea13b384b610d8f155676Steve Naroffint main()
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer{
30e2563ca02a519c2ad6d64dfed87d6e86c5d3c072Sam Bishop  pthread_t tid;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  barrier = (pthread_barrier_t *) malloc(sizeof(*barrier));
337ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff  pthread_barrier_init(barrier, NULL, 2);
344b07b2968f87f3cd5a3d8c76145f1cbfd718d42dSebastian Redl
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  pthread_create(&tid, NULL, thread, NULL);
360c727a35718556866a978f64ac549d9798735f08Chris Lattner
376a0ef4b83c91a6d6d5acb4ed5577c4659fe022a3Anders Carlsson  pthread_barrier_wait(barrier);
386c36be5b383875b490684bcf439d6d427298c1afChris Lattner  /*
39ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek   * The sleep() call below ensures that the pthread_barrier_destroy() call
40ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek   * happens after the created thread has returned from pthread_barrier_wait().
41ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek   */
42ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek  sleep(1);
43ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek  pthread_barrier_destroy(barrier);
44ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek  free(barrier);
45ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek
46ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek  pthread_join(tid, NULL);
47ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek  return 0;
48ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek}
49ce2fc3a343ea6098a96d587071cee7299f11957aTed Kremenek