This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pthread_once on ARM SMP


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]