http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52839
--- Comment #12 from Alan Modra <amodra at gmail dot com> 2012-04-04 22:27:43 UTC --- glibc/ntpl/pthread_once.c: static int once_lock = LLL_LOCK_INITIALIZER; int __pthread_once (once_control, init_routine) pthread_once_t *once_control; void (*init_routine) (void); { /* XXX Depending on whether the LOCK_IN_ONCE_T is defined use a global lock variable or one which is part of the pthread_once_t object. */ if (*once_control == PTHREAD_ONCE_INIT) { lll_lock (once_lock, LLL_PRIVATE); /* XXX This implementation is not complete. It doesn't take cancelation and fork into account. */ if (*once_control == PTHREAD_ONCE_INIT) { init_routine (); *once_control = !PTHREAD_ONCE_INIT; } lll_unlock (once_lock, LLL_PRIVATE); } return 0; } strong_alias (__pthread_once, pthread_once) This is quite broken for weakly ordered memory model. Notice how a thread that sees *once_control != PTHREAD_ONCE_INIT has no barriers at all. That means the read of *once_control has no ordering with respect to what happened on the thread that ran init_routine.