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;
59 T(pthread_create(&t1, 0, start, (void*[]){&once,&s1}));
60 T(pthread_create(&t2, 0, start, (void*[]){&once,&s2}));
61 T(pthread_create(&t3, 0, start, (void*[]){&once,&s3}));
62 if (!deadlocked(&s1)) T(pthread_join(t1,&p));
63 if (!deadlocked(&s2)) T(pthread_join(t2,&p));
64 if (!deadlocked(&s3)) T(pthread_join(t3,&p));
66 t_error("pthread_once ran init %d times instead of once\n", count);