1 // commit: 7e6be42a77989c01155bdc7333ea58206e1563d4 2011-03-08
2 // pthread_once should not deadlock
9 #define T(f) if ((r=(f))) t_error(#f " failed: %s\n", strerror(r))
10 #define E(f) if (f) t_error(#f " failed: %s\n", strerror(errno))
14 static void init(void)
19 static void *start(void *arg)
24 T(pthread_once(a[0], init));
29 static int deadlocked(sem_t *s)
34 E(clock_gettime(CLOCK_REALTIME, &ts));
35 ts.tv_nsec += 100*1000*1000;
36 if (ts.tv_nsec >= 1000*1000*1000) {
37 ts.tv_nsec -= 1000*1000*1000;
41 E(sem_timedwait(s,&ts));
42 if (errno != ETIMEDOUT)
44 t_error("pthread_once deadlocked\n");
51 pthread_once_t once = PTHREAD_ONCE_INIT;
53 void *a1[] = {&once, &s1};
54 void *a2[] = {&once, &s2};
55 void *a3[] = {&once, &s3};
62 T(pthread_create(&t1, 0, start, a1));
63 T(pthread_create(&t2, 0, start, a2));
64 T(pthread_create(&t3, 0, start, a3));
65 if (!deadlocked(&s1)) T(pthread_join(t1,&p));
66 if (!deadlocked(&s2)) T(pthread_join(t2,&p));
67 if (!deadlocked(&s3)) T(pthread_join(t3,&p));
69 t_error("pthread_once ran init %d times instead of once\n", count);