#include #include #include pthread_once_t once, once0 = PTHREAD_ONCE_INIT; int done = 0; static void init(void) { done = 1; } static void * thread(void *cookie) { pthread_barrier_t *bar = cookie; (void)pthread_barrier_wait(bar); pthread_once(&once, &init); if (!done) errx(1, "fail"); } int main(int argc, char **argv) { enum { N = 256 }; unsigned n = argc == 2 ? atoi(argv[1]) : 16; if (n > N) errx(1, "too many"); for (;;) { pthread_barrier_t bar; pthread_t t[N]; unsigned i; int error; error = pthread_barrier_init(&bar, NULL, n + 1); if (error) errc(1, error, "pthread_barrier_init"); for (i = 0; i < n; i++) { error = pthread_create(&t[i], NULL, &thread, &bar); if (error) errc(1, error, "pthread_create"); } once = once0; done = 0; (void)pthread_barrier_wait(&bar); for (i = 0; i < n; i++) { error = pthread_join(t[i], NULL); if (error) errc(1, error, "pthread_join"); } error = pthread_barrier_destroy(&bar); if (error) errc(1, error, "pthread_barrier_destroy"); } }