WRITE_MEMORY_BARRIER();
int __pthread_unlock(struct _pthread_fastlock * lock){#if defined HAS_COMPARE_AND_SWAP  long oldstatus;  pthread_descr thr, * ptr, * maxptr;  int maxprio;#endif#if defined TEST_FOR_COMPARE_AND_SWAP  if (!__pthread_has_cas)#endif#if !defined HAS_COMPARE_AND_SWAP  {    lock->__spinlock = 0;    WRITE_MEMORY_BARRIER();    return 0;  }#endif#if defined HAS_COMPARE_AND_SWAPagain:  oldstatus = lock->__status;  while ((oldstatus = lock->__status) == 1) {    if (__compare_and_swap_with_release_semantics(&lock->__status, 	oldstatus, 0))      return 0;  }  /* Find thread in waiting queue with maximal priority */  ptr = (pthread_descr *) &lock->__status;  thr = (pthread_descr) (oldstatus & ~1L);  maxprio = 0;  maxptr = ptr;  while (thr != 0) {    if (thr->p_priority >= maxprio) {      maxptr = ptr;      maxprio = thr->p_priority;    }    ptr = &(thr->p_nextlock);    /* Prevent reordering of the load of lock->__status above and the       load of *ptr below, as well as reordering of *ptr between       several iterations of the while loop.  Some processors (e.g.       multiprocessor Alphas) could perform such reordering even though       the loads are dependent. */    READ_MEMORY_BARRIER();    thr = *ptr;  }  /* Prevent reordering of the load of lock->__status above and     thr->p_nextlock below */  READ_MEMORY_BARRIER();  /* Remove max prio thread from waiting list. */  if (maxptr == (pthread_descr *) &lock->__status) {    /* If max prio thread is at head, remove it with compare-and-swap       to guard against concurrent lock operation. This removal       also has the side effect of marking the lock as released       because the new status comes from thr->p_nextlock whose       least significant bit is clear. */    thr = (pthread_descr) (oldstatus & ~1L);    if (! __compare_and_swap_with_release_semantics	    (&lock->__status, oldstatus, (long)(thr->p_nextlock)))      goto again;  } else {    /* No risk of concurrent access, remove max prio thread normally.       But in this case we must also flip the least significant bit       of the status to mark the lock as released. */    thr = *maxptr;    *maxptr = thr->p_nextlock;    do {      oldstatus = lock->__status;    } while (!__compare_and_swap_with_release_semantics(&lock->__status,	     oldstatus, oldstatus & ~1L));  }  /* Prevent reordering of store to *maxptr above and store to thr->p_nextlock     below */  WRITE_MEMORY_BARRIER();  /* Wake up the selected waiting thread */  thr->p_nextlock = NULL;  restart(thr);  return 0;#endif}