2 /* This program checks that Helgrind reports the five degenerate
3 uses of the barrier functions shown. */
12 void* child1 ( void* arg
)
14 pthread_barrier_wait( (pthread_barrier_t
*)arg
);
18 void *sleep1 ( void* arg
)
20 /* Long sleep, we hope to never trigger. */
22 pthread_barrier_wait ( (pthread_barrier_t
*)arg
);
26 void *exit1 ( void* arg
)
28 /* Sleep a bit, then exit, we are done. */
36 pthread_barrier_t
*bar1
, *bar2
, *bar3
, *bar4
, *bar5
;
37 /* int r; unused since pthread_cancel are commented out */
38 pthread_t thr1
, thr2
, slp1
, slp2
, ext1
;
40 /* initialise a barrier with a zero count */
41 fprintf(stderr
, "\ninitialise a barrier with zero count\n");
42 bar1
= malloc(sizeof(pthread_barrier_t
));
43 pthread_barrier_init(bar1
, NULL
, 0);
45 /* initialise a barrier twice */
46 fprintf(stderr
, "\ninitialise a barrier twice\n");
47 bar2
= malloc(sizeof(pthread_barrier_t
));
48 pthread_barrier_init(bar2
, NULL
, 1);
49 pthread_barrier_init(bar2
, NULL
, 1);
51 /* initialise a barrier which has threads waiting on it.
52 This isn't too simple. */
53 fprintf(stderr
, "\ninitialise a barrier which has threads waiting on it\n");
54 bar3
= malloc(sizeof(pthread_barrier_t
));
55 pthread_barrier_init(bar3
, NULL
, 2);
56 /* create a thread, whose purpose is to "unblock" the barrier after
57 some sleeping in case it keeps being blocked. */
58 pthread_create(&slp1
, NULL
, sleep1
, (void*)bar3
);
59 /* create a thread, whose only purpose is to block on the barrier */
60 pthread_create(&thr1
, NULL
, child1
, (void*)bar3
);
61 /* guarantee that it gets there first */
63 /* and now reinitialise */
64 pthread_barrier_init(bar3
, NULL
, 3);
66 /* destroy a barrier that has threads waiting at it */
67 fprintf(stderr
, "\ndestroy a barrier that has waiting threads\n");
68 /* once again, create a thread, whose only purpose is to block. */
69 bar4
= malloc(sizeof(pthread_barrier_t
));
70 pthread_barrier_init(bar4
, NULL
, 2);
71 /* create a thread, whose purpose is to "unblock" the barrier after
72 some sleeping in case it keeps being blocked. We hope it isn't
73 needed, but if it is, because pthread_barier_destroy hangs
74 and we will get an extra warning about the barrier being already
76 pthread_create(&slp2
, NULL
, sleep1
, (void*)bar4
);
77 /* create a thread, whose only purpose is to block on the barrier */
78 pthread_create(&thr2
, NULL
, child1
, (void*)bar4
);
79 /* guarantee that it gets there first */
82 pthread_barrier_destroy(bar4
);
86 /* destroy a barrier that was never initialised. This is a bit
87 tricky, in that we have to fill the barrier with bytes which
88 ensure that the pthread_barrier_destroy call doesn't crash for
89 some reason. One-fill seems to work ok on amd64-linux (glibc
91 fprintf(stderr
, "\ndestroy a barrier that was never initialised\n");
92 /* Create a thread that just exits the process after some sleep.
93 We are really done at this point, even if we hang. */
94 pthread_create(&ext1
, NULL
, exit1
, NULL
);
95 bar5
= malloc(sizeof(pthread_barrier_t
));
97 memset(bar5
, 1, sizeof(*bar5
));
98 pthread_barrier_destroy(bar5
);
100 /* now we need to clean up the mess .. But skip canceling threads. */
101 /* r= pthread_cancel(thr1); assert(!r); // drd doesn't like it. Just exit.
102 r= pthread_cancel(thr2); assert(!r); */
104 free(bar1
); free(bar2
); free(bar3
); free(bar4
); free(bar5
);
106 /* Use exit, we want to kill any "sleeper threads". */