This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
pthread_once on ARM SMP
- From: Jan Klötzke <jan at kloetzke dot net>
- To: libc-help at sourceware dot org
- Date: Fri, 11 Oct 2013 20:59:01 +0200
- Subject: pthread_once on ARM SMP
- Authentication-results: sourceware.org; auth=none
Hi,
While debugging something else I stumbled across the pthread_once
implementation of glibc. Looking at it I have the feeling that it is actually
not 100% safe on SMP. Quoting the relevant fast path code from
ports/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c:
int
__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
{
for (;;)
{
int oldval;
int newval;
[...]
do
{
newval = __fork_generation | 1;
oldval = *once_control;
if (oldval & 2)
break;
} while (atomic_compare_and_exchange_val_acq (once_control, newval,
oldval) != oldval);
/* Check if the initializer has already been done. */
if ((oldval & 2) != 0)
return 0;
[...]
}
[...]
init_routine ();
pthread_cleanup_pop (0);
*once_control = __fork_generation | 2;
[...]
}
In the fast path ((oldval & 2) != 0) I don't actually see a memory barrier
which would prevent the processor from reordering reads. In particular the CPU
might reorder reads that should happen after the once_control check.
Likewise, shouldn't the assignment of once_control at the end involve some
kind of barrier too? Otherwise the once_control assignment might be observable
on another CPU before the side effects of init_routine(), right? Do I overlook
something fundamentally here?
Regards,
Jan
PS. I am not subscribed to libc-help mailing, so please cc me on responses.