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