queue_init (&rwlock->rw_read_waiting); release (&rwlock->rw_spinlock);
rwlock->rw_read_waiting = NULL; __pthread_unlock (&rwlock->rw_lock);
pthread_rwlock_unlock (pthread_rwlock_t *rwlock){  struct _pthread_queue torestart;  pthread_descr th;  acquire (&rwlock->rw_spinlock);  if (rwlock->rw_writer != NULL)    {      /* Unlocking a write lock.  */      if (rwlock->rw_writer != thread_self ())	{	  release (&rwlock->rw_spinlock);	  return EPERM;	}      rwlock->rw_writer = NULL;      if (rwlock->rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP	  || (th = dequeue (&rwlock->rw_write_waiting)) == NULL)	{	  /* Restart all waiting readers.  */	  torestart = rwlock->rw_read_waiting;	  queue_init (&rwlock->rw_read_waiting);	  release (&rwlock->rw_spinlock);	  while ((th = dequeue (&torestart)) != NULL)	    restart (th);	}      else	{	  /* Restart one waiting writer.  */	  release (&rwlock->rw_spinlock);	  restart (th);	}    }  else    {      /* Unlocking a read lock.  */      if (rwlock->rw_readers == 0)	{	  release (&rwlock->rw_spinlock);	  return EPERM;	}      --rwlock->rw_readers;      if (rwlock->rw_readers == 0)	/* Restart one waiting writer, if any.  */	th = dequeue (&rwlock->rw_write_waiting);      else	th = NULL;      release (&rwlock->rw_spinlock);      if (th != NULL)	restart (th);    }  return 0;}