PPC pthread_spin_init appears broken.

Bret Ketchum bret_ketchum at cnt.com
Fri Sep 5 23:17:22 EST 2003

	Scanning through a couple of glibc sources (Redhat 2.3.2-11.9
and Yellow Dog 2.3.1-51a) it appears that pthread_spin_init is broken
for the PPC, at least the 32 bit variety. pthread_spin_init initializes the
to '1' but pthread_spin_lock calls compare_and_wait looking for a '0' as the

old value, to be swapped for a '1' when the old value is read. This can't
(without forcing the lock to '0') as the lock was first set to a '1' in

	Any enlightenment will be appreciated.

Code fragments from Redhat 2.3.2-11.9 below:


PT_EI int
__compare_and_swap (long int *p, long int oldval, long int newval)
  int ret;

  __asm__ __volatile__ (
           "0:    lwarx %0,0,%1 ;"
           "      xor. %0,%3,%0;"
           "      bne 1f;"
           "      stwcx. %2,0,%1;"
           "      bne- 0b;"
           "1:    "
        : "=&r"(ret)
        : "r"(p), "r"(newval), "r"(oldval)
        : "cr0", "memory");
  /* This version of __compare_and_swap is to be used when acquiring
     a lock, so we don't need to worry about whether other memory
     operations have completed, but we do need to be sure that any loads
     after this point really occur after we have acquired the lock.  */
  __asm__ __volatile__ ("isync" : : : "memory");
  return ret == 0;

__pthread_spin_lock (pthread_spinlock_t *lock)
  while (! __compare_and_swap ((long int *)lock, 0, 1))
  return 0;

__pthread_spin_unlock (pthread_spinlock_t *lock)
  *lock = 0;
  return 0;

__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
     all processes which can access the memory location `lock' points
     to can use the spinlock.  */
  *lock = 1;
  return 0;

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

More information about the Linuxppc-dev mailing list