/* POSIX reader--writer lock: core parts.
   Copyright (C) 2016-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <sysdep.h>
#include <pthread.h>
#include <pthreadP.h>
#include <sys/time.h>
#include <stap-probe.h>
#include <atomic.h>
#include <futex-internal.h>


/* A reader--writer lock that fulfills the POSIX requirements (but operations
   on this lock are not necessarily full barriers, as one may interpret the
   POSIX requirement about "synchronizing memory").  All critical sections are
   in a total order, writers synchronize with prior writers and readers, and
   readers synchronize with prior writers.

   A thread is allowed to acquire a read lock recursively (i.e., have rdlock
   critical sections that overlap in sequenced-before) unless the kind of the
   rwlock is set to PTHREAD_RWLOCK_PREFER_WRITERS_NONRECURSIVE_NP.

   This lock is built so that workloads of mostly readers can be executed with
   low runtime overheads.  This matches that the default kind of the lock is
   PTHREAD_RWLOCK_PREFER_READER_NP.  Acquiring a read lock requires a single
   atomic addition if the lock is or was previously acquired by other
   readers; releasing the lock is a single CAS if there are no concurrent
   writers.
   Workloads consisting of mostly writers are of secondary importance.
   An uncontended write lock acquisition is as fast as for a normal
   exclusive mutex but writer contention is somewhat more costly due to
   keeping track of the exact number of writers.  If the rwlock kind requests
   writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITERS_NP or the
   no-recursive-readers variant of it), then writer--to--writer lock ownership
   hand-over is fairly fast and bypasses lock acquisition attempts by readers.
   The costs of lock ownership transfer between readers and writers vary.  If
   the program asserts that there are no recursive readers and writers are
   preferred, then write lock acquisition attempts will block subsequent read
   lock acquisition attempts, so that new incoming readers do not prolong a
   phase in which readers have acquired the lock.

   The main components of the rwlock are a writer-only lock that allows only
   one of the concurrent writers to be the primary writer, and a
   single-writer-multiple-readers lock that decides between read phases, in
   which readers have acquired the rwlock, and write phases in which a primary
   writer or a sequence of different primary writers have acquired the rwlock.

   The single-writer-multiple-readers lock is the central piece of state
   describing the rwlock and is encoded in the __readers field (see below for
   a detailed explanation):

   State WP  WL  R   RW  Notes
   ---------------------------
   #1    0   0   0   0   Lock is idle (and in a read phase).
   #2    0   0   >0  0   Readers have acquired the lock.
   #3    0   1   0   0   Lock is not acquired; a writer will try to start a
			 write phase.
   #4    0   1   >0  0   Readers have acquired the lock; a writer is waiting
			 and explicit hand-over to the writer is required.
   #4a   0   1   >0  1   Same as #4 except that there are further readers
			 waiting because the writer is to be preferred.
   #5    1   0   0   0   Lock is idle (and in a write phase).
   #6    1   0   >0  0   Write phase; readers will try to start a read phase
			 (requires explicit hand-over to all readers that
			 do not start the read phase).
   #7    1   1   0   0   Lock is acquired by a writer.
   #8    1   1   >0  0   Lock acquired by a writer and readers are waiting;
			 explicit hand-over to the readers is required.

   WP (PTHREAD_RWLOCK_WRPHASE) is true if the lock is in a write phase, so
   potentially acquired by a primary writer.
   WL (PTHREAD_RWLOCK_WRLOCKED) is true if there is a primary writer (i.e.,
   the thread that was able to set this bit from false to true).
   R (all bits in __readers except the number of least-significant bits
   denoted in PTHREAD_RWLOCK_READER_SHIFT) is the number of readers that have
   or are trying to acquired the lock.  There may be more readers waiting if
   writers are preferred and there will be no recursive readers, in which
   case RW (PTHREAD_RWLOCK_RWAITING) is true in state #4a.

   We want to block using futexes but using __readers as a futex word directly
   is not a good solution.  First, we want to wait on different conditions
   such as waiting for a phase change vs. waiting for the primary writer to
   release the writer-only lock.  Second, the number of readers could change
   frequently, which would make it likely that a writer's futex_wait fails
   frequently too because the expected value does not match the value of
   __readers anymore.
   Therefore, we split out the futex words into the __wrphase_futex and
   __writers_futex fields.  The former tracks the value of the WP bit and is
   changed after changing WP by the thread that changes WP.  However, because
   of the POSIX requirements regarding mutex/rwlock destruction (i.e., that
   destroying a rwlock is allowed as soon as no thread has acquired or will
   acquire the lock), we have to be careful and hand over lock ownership (via
   a phase change) carefully to those threads waiting.  Specifically, we must
   prevent a situation in which we are not quite sure whether we still have
   to unblock another thread through a change to memory (executing a
   futex_wake on a former futex word that is now used for something else is
   fine).
   The scheme we use for __wrphase_futex is that waiting threads that may
   use the futex word to block now all have to use the futex word to block; it
   is not allowed to take the short-cut and spin-wait on __readers because
   then the waking thread cannot just make one final change to memory to
   unblock all potentially waiting threads.  If, for example, a reader
   increments R in states #7 or #8, it has to then block until __wrphase_futex
   is 0 and it can confirm that the value of 0 was stored by the primary
   writer; in turn, the primary writer has to change to a read phase too when
   releasing WL (i.e., to state #2), and it must change __wrphase_futex to 0
   as the next step.  This ensures that the waiting reader will not be able to
   acquire, release, and then destroy the lock concurrently with the pending
   futex unblock operations by the former primary writer.  This scheme is
   called explicit hand-over in what follows.
   Note that waiting threads can cancel waiting only if explicit hand-over has
   not yet started (e.g., if __readers is still in states #7 or #8 in the
   example above).

   Writers determine the primary writer through WL.  Blocking using futexes
   is performed using __writers_futex as a futex word; primary writers will
   enable waiting on this futex by setting it to 1 after they acquired the WL
   bit and will disable waiting by setting it to 0 before they release WL.
   This leaves small windows where blocking using futexes is not possible
   although a primary writer exists, but in turn decreases complexity of the
   writer--writer synchronization and does not affect correctness.
   If writers are preferred, writers can hand over WL directly to other
   waiting writers that registered by incrementing __writers:  If the primary
   writer can CAS __writers from a non-zero value to the same value with the
   PTHREAD_RWLOCK_WRHANDOVER bit set, it effectively transfers WL ownership
   to one of the registered waiting writers and does not reset WL; in turn,
   a registered writer that can clear PTHREAD_RWLOCK_WRHANDOVER using a CAS
   then takes over WL.  Note that registered waiting writers can cancel
   waiting by decrementing __writers, but the last writer to unregister must
   become the primary writer if PTHREAD_RWLOCK_WRHANDOVER is set.
   Also note that adding another state/bit to signal potential writer--writer
   contention (e.g., as done in the normal mutex algorithm) would not be
   helpful because we would have to conservatively assume that there is in
   fact no other writer, and wake up readers too.

   To avoid having to call futex_wake when no thread uses __wrphase_futex or
   __writers_futex, threads will set the PTHREAD_RWLOCK_FUTEX_USED bit in the
   respective futex words before waiting on it (using a CAS so it will only be
   set if in a state in which waiting would be possible).  In the case of
   __writers_futex, we wake only one thread but several threads may share
   PTHREAD_RWLOCK_FUTEX_USED, so we must assume that there are still others.
   This is similar to what we do in pthread_mutex_lock.  We do not need to
   do this for __wrphase_futex because there, we always wake all waiting
   threads.

   Blocking in the state #4a simply uses __readers as futex word.  This
   simplifies the algorithm but suffers from some of the drawbacks discussed
   before, though not to the same extent because R can only decrease in this
   state, so the number of potentially failing futex_wait attempts will be
   bounded.  All threads moving from state #4a to another state must wake
   up threads blocked on the __readers futex.

   The ordering invariants that we have to take care of in the implementation
   are primarily those necessary for a reader--writer lock; this is rather
   straightforward and happens during write/read phase switching (potentially
   through explicit hand-over), and between writers through synchronization
   involving the PTHREAD_RWLOCK_WRLOCKED or PTHREAD_RWLOCK_WRHANDOVER bits.
   Additionally, we need to take care that modifications of __writers_futex
   and __wrphase_futex (e.g., by otherwise unordered readers) take place in
   the writer critical sections or read/write phases, respectively, and that
   explicit hand-over observes stores from the previous phase.  How this is
   done is explained in more detail in comments in the code.

   Many of the accesses to the futex words just need relaxed MO.  This is
   possible because we essentially drive both the core rwlock synchronization
   and the futex synchronization in parallel.  For example, an unlock will
   unlock the rwlock and take part in the futex synchronization (using
   PTHREAD_RWLOCK_FUTEX_USED, see above); even if they are not tightly
   ordered in some way, the futex synchronization ensures that there are no
   lost wake-ups, and woken threads will then eventually see the most recent
   state of the rwlock.  IOW, waiting threads will always be woken up, while
   not being able to wait using futexes (which can happen) is harmless; in
   turn, this means that waiting threads don't need special ordering wrt.
   waking threads.

   The futex synchronization consists of the three-state futex word:
   (1) cannot block on it, (2) can block on it, and (3) there might be a
   thread blocked on it (i.e., with PTHREAD_RWLOCK_FUTEX_USED set).
   Relaxed-MO atomic read-modify-write operations are sufficient to maintain
   this (e.g., using a CAS to go from (2) to (3) but not from (1) to (3)),
   but we need ordering of the futex word modifications by the waking threads
   so that they collectively make correct state changes between (1)-(3).
   The futex-internal synchronization (i.e., the conceptual critical sections
   around futex operations in the kernel) then ensures that even an
   unconstrained load (i.e., relaxed MO) inside of futex_wait will not lead to
   lost wake-ups because either the waiting thread will see the change from
   (3) to (1) when a futex_wake came first, or this futex_wake will wake this
   waiting thread because the waiting thread came first.


   POSIX allows but does not require rwlock acquisitions to be a cancellation
   point.  We do not support cancellation.

   TODO We do not try to elide any read or write lock acquisitions currently.
   While this would be possible, it is unclear whether HTM performance is
   currently predictable enough and our runtime tuning is good enough at
   deciding when to use elision so that enabling it would lead to consistently
   better performance.  */


static int
__pthread_rwlock_get_private (pthread_rwlock_t *rwlock)
{
  return rwlock->__data.__shared != 0 ? FUTEX_SHARED : FUTEX_PRIVATE;
}

static __always_inline void
__pthread_rwlock_rdunlock (pthread_rwlock_t *rwlock)
{
  int private = __pthread_rwlock_get_private (rwlock);
  /* We decrease the number of readers, and if we are the last reader and
     there is a primary writer, we start a write phase.  We use a CAS to
     make this atomic so that it is clear whether we must hand over ownership
     explicitly.  */
  unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
  unsigned int rnew;
  for (;;)
    {
      rnew = r - (1 << PTHREAD_RWLOCK_READER_SHIFT);
      /* If we are the last reader, we also need to unblock any readers
	 that are waiting for a writer to go first (PTHREAD_RWLOCK_RWAITING)
	 so that they can register while the writer is active.  */
      if ((rnew >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
	{
	  if ((rnew & PTHREAD_RWLOCK_WRLOCKED) != 0)
	    rnew |= PTHREAD_RWLOCK_WRPHASE;
	  rnew &= ~(unsigned int) PTHREAD_RWLOCK_RWAITING;
	}
      /* We need release MO here for three reasons.  First, so that we
	 synchronize with subsequent writers.  Second, we might have been the
	 first reader and set __wrphase_futex to 0, so we need to synchronize
	 with the last reader that will set it to 1 (note that we will always
	 change __readers before the last reader, or we are the last reader).
	 Third, a writer that takes part in explicit hand-over needs to see
	 the first reader's store to __wrphase_futex (or a later value) if
	 the writer observes that a write phase has been started.  */
      if (atomic_compare_exchange_weak_release (&rwlock->__data.__readers,
	  &r, rnew))
	break;
      /* TODO Back-off.  */
    }
  if ((rnew & PTHREAD_RWLOCK_WRPHASE) != 0)
    {
      /* We need to do explicit hand-over.  We need the acquire MO fence so
	 that our modification of _wrphase_futex happens after a store by
	 another reader that started a read phase.  Relaxed MO is sufficient
	 for the modification of __wrphase_futex because it is just used
	 to delay acquisition by a writer until all threads are unblocked
	 irrespective of whether they are looking at __readers or
	 __wrphase_futex; any other synchronizes-with relations that are
	 necessary are established through __readers.  */
      atomic_thread_fence_acquire ();
      if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 1)
	   & PTHREAD_RWLOCK_FUTEX_USED) != 0)
	futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
    }
  /* Also wake up waiting readers if we did reset the RWAITING flag.  */
  if ((r & PTHREAD_RWLOCK_RWAITING) != (rnew & PTHREAD_RWLOCK_RWAITING))
    futex_wake (&rwlock->__data.__readers, INT_MAX, private);
}


static __always_inline int
__pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
    const struct timespec *abstime)
{
  unsigned int r;

  /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
     situation we recognize and report.  */
  if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
      == THREAD_GETMEM (THREAD_SELF, tid)))
    return EDEADLK;

  /* If we prefer writers, recursive rdlock is disallowed, we are in a read
     phase, and there are other readers present, we try to wait without
     extending the read phase.  We will be unblocked by either one of the
     other active readers, or if the writer gives up WRLOCKED (e.g., on
     timeout).
     If there are no other readers, we simply race with any existing primary
     writer; it would have been a race anyway, and changing the odds slightly
     will likely not make a big difference.  */
  if (rwlock->__data.__flags == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
    {
      r = atomic_load_relaxed (&rwlock->__data.__readers);
      while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
	      && ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
	      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) > 0))
	{
	  /* TODO Spin first.  */
	  /* Try setting the flag signaling that we are waiting without having
	     incremented the number of readers.  Relaxed MO is fine because
	     this is just about waiting for a state change in __readers.  */
	  if (atomic_compare_exchange_weak_relaxed
	      (&rwlock->__data.__readers, &r, r | PTHREAD_RWLOCK_RWAITING))
	    {
	      /* Wait for as long as the flag is set.  An ABA situation is
		 harmless because the flag is just about the state of
		 __readers, and all threads set the flag under the same
		 conditions.  */
	      while ((atomic_load_relaxed (&rwlock->__data.__readers)
		  & PTHREAD_RWLOCK_RWAITING) != 0)
		{
		  int private = __pthread_rwlock_get_private (rwlock);
		  int err = futex_abstimed_wait (&rwlock->__data.__readers,
		      r, abstime, private);
		  /* We ignore EAGAIN and EINTR.  On time-outs, we can just
		     return because we don't need to clean up anything.  */
		  if (err == ETIMEDOUT)
		    return err;
		}
	      /* It makes sense to not break out of the outer loop here
		 because we might be in the same situation again.  */
	    }
	  else
	    {
	      /* TODO Back-off.  */
	    }
	}
    }
  /* Register as a reader, using an add-and-fetch so that R can be used as
     expected value for future operations.  Acquire MO so we synchronize with
     prior writers as well as the last reader of the previous read phase (see
     below).  */
  r = atomic_fetch_add_acquire (&rwlock->__data.__readers,
      (1 << PTHREAD_RWLOCK_READER_SHIFT)) + (1 << PTHREAD_RWLOCK_READER_SHIFT);

  /* Check whether there is an overflow in the number of readers.  We assume
     that the total number of threads is less than half the maximum number
     of readers that we have bits for in __readers (i.e., with 32-bit int and
     PTHREAD_RWLOCK_READER_SHIFT of 3, we assume there are less than
     1 << (32-3-1) concurrent threads).
     If there is an overflow, we use a CAS to try to decrement the number of
     readers if there still is an overflow situation.  If so, we return
     EAGAIN; if not, we are not a thread causing an overflow situation, and so
     we just continue.  Using a fetch-add instead of the CAS isn't possible
     because other readers might release the lock concurrently, which could
     make us the last reader and thus responsible for handing ownership over
     to writers (which requires a CAS too to make the decrement and ownership
     transfer indivisible).  */
  while (__glibc_unlikely (r >= PTHREAD_RWLOCK_READER_OVERFLOW))
    {
      /* Relaxed MO is okay because we just want to undo our registration and
	 cannot have changed the rwlock state substantially if the CAS
	 succeeds.  */
      if (atomic_compare_exchange_weak_relaxed (&rwlock->__data.__readers, &r,
	  r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
	return EAGAIN;
    }

  /* We have registered as a reader, so if we are in a read phase, we have
     acquired a read lock.  This is also the reader--reader fast-path.
     Even if there is a primary writer, we just return.  If writers are to
     be preferred and we are the only active reader, we could try to enter a
     write phase to let the writer proceed.  This would be okay because we
     cannot have acquired the lock previously as a reader (which could result
     in deadlock if we would wait for the primary writer to run).  However,
     this seems to be a corner case and handling it specially not be worth the
     complexity.  */
  if (__glibc_likely ((r & PTHREAD_RWLOCK_WRPHASE) == 0))
    return 0;
  /* Otherwise, if we were in a write phase (states #6 or #8), we must wait
     for explicit hand-over of the read phase; the only exception is if we
     can start a read phase if there is no primary writer currently.  */
  while (((r & PTHREAD_RWLOCK_WRPHASE) != 0)
      && ((r & PTHREAD_RWLOCK_WRLOCKED) == 0))
    {
       /* Try to enter a read phase: If the CAS below succeeds, we have
	 ownership; if it fails, we will simply retry and reassess the
	 situation.
	 Acquire MO so we synchronize with prior writers.  */
      if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
	  r ^ PTHREAD_RWLOCK_WRPHASE))
	{
	  /* We started the read phase, so we are also responsible for
	     updating the write-phase futex.  Relaxed MO is sufficient.
	     We have to do the same steps as a writer would when handing
	     over the read phase to us because other readers cannot
	     distinguish between us and the writer; this includes
	     explicit hand-over and potentially having to wake other readers
	     (but we can pretend to do the setting and unsetting of WRLOCKED
	     atomically, and thus can skip this step).  */
	  if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
	      & PTHREAD_RWLOCK_FUTEX_USED) != 0)
	    {
	      int private = __pthread_rwlock_get_private (rwlock);
	      futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
	    }
	  return 0;
	}
      else
	{
	  /* TODO Back off before retrying.  Also see above.  */
	}
    }

  /* We were in a write phase but did not install the read phase.  We cannot
     distinguish between a writer and another reader starting the read phase,
     so we must wait for explicit hand-over via __wrphase_futex.
     However, __wrphase_futex might not have been set to 1 yet (either
     because explicit hand-over to the writer is still ongoing, or because
     the writer has started the write phase but has not yet updated
     __wrphase_futex).  The least recent value of __wrphase_futex we can
     read from here is the modification of the last read phase (because
     we synchronize with the last reader in this read phase through
     __readers; see the use of acquire MO on the fetch_add above).
     Therefore, if we observe a value of 0 for __wrphase_futex, we need
     to subsequently check that __readers now indicates a read phase; we
     need to use acquire MO for this so that if we observe a read phase,
     we will also see the modification of __wrphase_futex by the previous
     writer.  We then need to load __wrphase_futex again and continue to
     wait if it is not 0, so that we do not skip explicit hand-over.
     Relaxed MO is sufficient for the load from __wrphase_futex because
     we just use it as an indicator for when we can proceed; we use
     __readers and the acquire MO accesses to it to eventually read from
     the proper stores to __wrphase_futex.  */
  unsigned int wpf;
  bool ready = false;
  for (;;)
    {
      while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
	  | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
	{
	  int private = __pthread_rwlock_get_private (rwlock);
	  if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
	      && !atomic_compare_exchange_weak_relaxed
		  (&rwlock->__data.__wrphase_futex,
		   &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))
	    continue;
	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
	      1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
	  if (err == ETIMEDOUT)
	    {
	      /* If we timed out, we need to unregister.  If no read phase
		 has been installed while we waited, we can just decrement
		 the number of readers.  Otherwise, we just acquire the
		 lock, which is allowed because we give no precise timing
		 guarantees, and because the timeout is only required to
		 be in effect if we would have had to wait for other
		 threads (e.g., if futex_wait would time-out immediately
		 because the given absolute time is in the past).  */
	      r = atomic_load_relaxed (&rwlock->__data.__readers);
	      while ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
		{
		  /* We don't need to make anything else visible to
		     others besides unregistering, so relaxed MO is
		     sufficient.  */
		  if (atomic_compare_exchange_weak_relaxed
		      (&rwlock->__data.__readers, &r,
		       r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
		    return ETIMEDOUT;
		  /* TODO Back-off.  */
		}
	      /* Use the acquire MO fence to mirror the steps taken in the
		 non-timeout case.  Note that the read can happen both
		 in the atomic_load above as well as in the failure case
		 of the CAS operation.  */
	      atomic_thread_fence_acquire ();
	      /* We still need to wait for explicit hand-over, but we must
		 not use futex_wait anymore because we would just time out
		 in this case and thus make the spin-waiting we need
		 unnecessarily expensive.  */
	      while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex)
		  | PTHREAD_RWLOCK_FUTEX_USED)
		  == (1 | PTHREAD_RWLOCK_FUTEX_USED))
		{
		  /* TODO Back-off?  */
		}
	      ready = true;
	      break;
	    }
	  /* If we got interrupted (EINTR) or the futex word does not have the
	     expected value (EAGAIN), retry.  */
	}
      if (ready)
	/* See below.  */
	break;
      /* We need acquire MO here so that we synchronize with the lock
	 release of the writer, and so that we observe a recent value of
	 __wrphase_futex (see below).  */
      if ((atomic_load_acquire (&rwlock->__data.__readers)
	  & PTHREAD_RWLOCK_WRPHASE) == 0)
	/* We are in a read phase now, so the least recent modification of
	   __wrphase_futex we can read from is the store by the writer
	   with value 1.  Thus, only now we can assume that if we observe
	   a value of 0, explicit hand-over is finished. Retry the loop
	   above one more time.  */
	ready = true;
    }

  return 0;
}


static __always_inline void
__pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
{
  int private = __pthread_rwlock_get_private (rwlock);

  atomic_store_relaxed (&rwlock->__data.__cur_writer, 0);
  /* Disable waiting by writers.  We will wake up after we decided how to
     proceed.  */
  bool wake_writers = ((atomic_exchange_relaxed
      (&rwlock->__data.__writers_futex, 0) & PTHREAD_RWLOCK_FUTEX_USED) != 0);

  if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
    {
      /* First, try to hand over to another writer.  */
      unsigned int w = atomic_load_relaxed (&rwlock->__data.__writers);
      while (w != 0)
	{
	  /* Release MO so that another writer that gets WRLOCKED from us will
	     synchronize with us and thus can take over our view of
	     __readers (including, for example, whether we are in a write
	     phase or not).  */
	  if (atomic_compare_exchange_weak_release (&rwlock->__data.__writers,
	      &w, w | PTHREAD_RWLOCK_WRHANDOVER))
	    /* Another writer will take over.  */
	    goto done;
	  /* TODO Back-off.  */
	}
    }

  /* We have done everything we needed to do to prefer writers, so now we
     either hand over explicitly to readers if there are any, or we simply
     stay in a write phase.  See pthread_rwlock_rdunlock for more details.  */
  unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
  /* Release MO so that subsequent readers or writers synchronize with us.  */
  while (!atomic_compare_exchange_weak_release
      (&rwlock->__data.__readers, &r, (r ^ PTHREAD_RWLOCK_WRLOCKED)
	  ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
	      : PTHREAD_RWLOCK_WRPHASE)))
    {
      /* TODO Back-off.  */
    }
  if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
    {
      /* We must hand over explicitly through __wrphase_futex.  Relaxed MO is
	 sufficient because it is just used to delay acquisition by a writer;
	 any other synchronizes-with relations that are necessary are
	 established through __readers.  */
      if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
	   & PTHREAD_RWLOCK_FUTEX_USED) != 0)
	futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
    }

 done:
  /* We released WRLOCKED in some way, so wake a writer.  */
  if (wake_writers)
    futex_wake (&rwlock->__data.__writers_futex, 1, private);
}


static __always_inline int
__pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
    const struct timespec *abstime)
{
  /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
     situation we recognize and report.  */
  if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
      == THREAD_GETMEM (THREAD_SELF, tid)))
    return EDEADLK;

  /* First we try to acquire the role of primary writer by setting WRLOCKED;
     if it was set before, there already is a primary writer.  Acquire MO so
     that we synchronize with previous primary writers.

     We do not try to change to a write phase right away using a fetch_or
     because we would have to reset it again and wake readers if there are
     readers present (some readers could try to acquire the lock more than
     once, so setting a write phase in the middle of this could cause
     deadlock).  Changing to a write phase eagerly would only speed up the
     transition from a read phase to a write phase in the uncontended case,
     but it would slow down the contended case if readers are preferred (which
     is the default).
     We could try to CAS from a state with no readers to a write phase, but
     this could be less scalable if readers arrive and leave frequently.  */
  bool may_share_futex_used_flag = false;
  unsigned int r = atomic_fetch_or_acquire (&rwlock->__data.__readers,
      PTHREAD_RWLOCK_WRLOCKED);
  if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRLOCKED) != 0))
    {
      /* There is another primary writer.  */
      bool prefer_writer =
	  (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP);
      if (prefer_writer)
	{
	  /* We register as a waiting writer, so that we can make use of
	     writer--writer hand-over.  Relaxed MO is fine because we just
	     want to register.  We assume that the maximum number of threads
	     is less than the capacity in __writers.  */
	  atomic_fetch_add_relaxed (&rwlock->__data.__writers, 1);
	}
      for (;;)
	{
	  /* TODO Spin until WRLOCKED is 0 before trying the CAS below.
	     But pay attention to not delay trying writer--writer hand-over
	     for too long (which we must try eventually anyway).  */
	  if ((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
	    {
	      /* Try to become the primary writer or retry.  Acquire MO as in
		 the fetch_or above.  */
	      if (atomic_compare_exchange_weak_acquire
		  (&rwlock->__data.__readers, &r,
		      r | PTHREAD_RWLOCK_WRLOCKED))
		{
		  if (prefer_writer)
		    {
		      /* Unregister as a waiting writer.  Note that because we
			 acquired WRLOCKED, WRHANDOVER will not be set.
			 Acquire MO on the CAS above ensures that
			 unregistering happens after the previous writer;
			 this sorts the accesses to __writers by all
			 primary writers in a useful way (e.g., any other
			 primary writer acquiring after us or getting it from
			 us through WRHANDOVER will see both our changes to
			 __writers).
			 ??? Perhaps this is not strictly necessary for
			 reasons we do not yet know of.  */
		      atomic_fetch_add_relaxed (&rwlock->__data.__writers,
			  -1);
		    }
		  break;
		}
	      /* Retry if the CAS fails (r will have been updated).  */
	      continue;
	    }
	  /* If writer--writer hand-over is available, try to become the
	     primary writer this way by grabbing the WRHANDOVER token.  If we
	     succeed, we own WRLOCKED.  */
	  if (prefer_writer)
	    {
	      unsigned int w = atomic_load_relaxed
		  (&rwlock->__data.__writers);
	      if ((w & PTHREAD_RWLOCK_WRHANDOVER) != 0)
		{
		  /* Acquire MO is required here so that we synchronize with
		     the writer that handed over WRLOCKED.  We also need this
		     for the reload of __readers below because our view of
		     __readers must be at least as recent as the view of the
		     writer that handed over WRLOCKED; we must avoid an ABA
		     through WRHANDOVER, which could, for example, lead to us
		     assuming we are still in a write phase when in fact we
		     are not.  */
		  if (atomic_compare_exchange_weak_acquire
		      (&rwlock->__data.__writers,
		       &w, (w - PTHREAD_RWLOCK_WRHANDOVER - 1)))
		    {
		      /* Reload so our view is consistent with the view of
			 the previous owner of WRLOCKED.  See above.  */
		      r = atomic_load_relaxed (&rwlock->__data.__readers);
		      break;
		    }
		  /* We do not need to reload __readers here.  We should try
		     to perform writer--writer hand-over if possible; if it
		     is not possible anymore, we will reload __readers
		     elsewhere in this loop.  */
		  continue;
		}
	    }
	  /* We did not acquire WRLOCKED nor were able to use writer--writer
	     hand-over, so we block on __writers_futex.  */
	  int private = __pthread_rwlock_get_private (rwlock);
	  unsigned int wf = atomic_load_relaxed
	      (&rwlock->__data.__writers_futex);
	  if (((wf & ~(unsigned int) PTHREAD_RWLOCK_FUTEX_USED) != 1)
	      || ((wf != (1 | PTHREAD_RWLOCK_FUTEX_USED))
		  && !atomic_compare_exchange_weak_relaxed
		      (&rwlock->__data.__writers_futex, &wf,
		       1 | PTHREAD_RWLOCK_FUTEX_USED)))
	    {
	      /* If we cannot block on __writers_futex because there is no
		 primary writer, or we cannot set PTHREAD_RWLOCK_FUTEX_USED,
		 we retry.  We must reload __readers here in case we cannot
		 block on __writers_futex so that we can become the primary
		 writer and are not stuck in a loop that just continuously
		 fails to block on __writers_futex.  */
	      r = atomic_load_relaxed (&rwlock->__data.__readers);
	      continue;
	    }
	  /* We set the flag that signals that the futex is used, or we could
	     have set it if we had been faster than other waiters.  As a
	     result, we may share the flag with an unknown number of other
	     writers.  Therefore, we must keep this flag set when we acquire
	     the lock.  We do not need to do this when we do not reach this
	     point here because then we are not part of the group that may
	     share the flag, and another writer will wake one of the writers
	     in this group.  */
	  may_share_futex_used_flag = true;
	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
	      1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
	  if (err == ETIMEDOUT)
	    {
	      if (prefer_writer)
		{
		  /* We need to unregister as a waiting writer.  If we are the
		     last writer and writer--writer hand-over is available,
		     we must make use of it because nobody else will reset
		     WRLOCKED otherwise.  (If we use it, we simply pretend
		     that this happened before the timeout; see
		     pthread_rwlock_rdlock_full for the full reasoning.)
		     Also see the similar code above.  */
		  unsigned int w = atomic_load_relaxed
		      (&rwlock->__data.__writers);
		  while (!atomic_compare_exchange_weak_acquire
		      (&rwlock->__data.__writers, &w,
			  (w == PTHREAD_RWLOCK_WRHANDOVER + 1 ? 0 : w - 1)))
		    {
		      /* TODO Back-off.  */
		    }
		  if (w == PTHREAD_RWLOCK_WRHANDOVER + 1)
		    {
		      /* We must continue as primary writer.  See above.  */
		      r = atomic_load_relaxed (&rwlock->__data.__readers);
		      break;
		    }
		}
	      /* We cleaned up and cannot have stolen another waiting writer's
		 futex wake-up, so just return.  */
	      return ETIMEDOUT;
	    }
	  /* If we got interrupted (EINTR) or the futex word does not have the
	     expected value (EAGAIN), retry after reloading __readers.  */
	  r = atomic_load_relaxed (&rwlock->__data.__readers);
	}
      /* Our snapshot of __readers is up-to-date at this point because we
	 either set WRLOCKED using a CAS (and update r accordingly below,
	 which was used as expected value for the CAS) or got WRLOCKED from
	 another writer whose snapshot of __readers we inherit.  */
      r |= PTHREAD_RWLOCK_WRLOCKED;
    }

  /* We are the primary writer; enable blocking on __writers_futex.  Relaxed
     MO is sufficient for futex words; acquire MO on the previous
     modifications of __readers ensures that this store happens after the
     store of value 0 by the previous primary writer.  */
  atomic_store_relaxed (&rwlock->__data.__writers_futex,
      1 | (may_share_futex_used_flag ? PTHREAD_RWLOCK_FUTEX_USED : 0));

  /* If we are in a write phase, we have acquired the lock.  */
  if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
    goto done;

  /* If we are in a read phase and there are no readers, try to start a write
     phase.  */
  while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0))
    {
      /* Acquire MO so that we synchronize with prior writers and do
	 not interfere with their updates to __writers_futex, as well
	 as regarding prior readers and their updates to __wrphase_futex,
	 respectively.  */
      if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
	  &r, r | PTHREAD_RWLOCK_WRPHASE))
	{
	  /* We have started a write phase, so need to enable readers to wait.
	     See the similar case in __pthread_rwlock_rdlock_full.  Unlike in
	     that similar case, we are the (only) primary writer and so do
	     not need to wake another writer.  */
	  atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);

	  goto done;
	}
      /* TODO Back-off.  */
    }

  /* We became the primary writer in a read phase and there were readers when
     we did (because of the previous loop).  Thus, we have to wait for
     explicit hand-over from one of these readers.
     We basically do the same steps as for the similar case in
     __pthread_rwlock_rdlock_full, except that we additionally might try
     to directly hand over to another writer and need to wake up
     other writers or waiting readers (i.e., PTHREAD_RWLOCK_RWAITING).  */
  unsigned int wpf;
  bool ready = false;
  for (;;)
    {
      while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
	  | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED)
	{
	  int private = __pthread_rwlock_get_private (rwlock);
	  if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
	      && !atomic_compare_exchange_weak_relaxed
		  (&rwlock->__data.__wrphase_futex, &wpf,
		   PTHREAD_RWLOCK_FUTEX_USED))
	    continue;
	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
	      PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
	  if (err == ETIMEDOUT)
	    {
	      if (rwlock->__data.__flags
		  != PTHREAD_RWLOCK_PREFER_READER_NP)
		{
		  /* We try writer--writer hand-over.  */
		  unsigned int w = atomic_load_relaxed
		      (&rwlock->__data.__writers);
		  if (w != 0)
		    {
		      /* We are about to hand over WRLOCKED, so we must
			 release __writers_futex too; otherwise, we'd have
			 a pending store, which could at least prevent
			 other threads from waiting using the futex
			 because it could interleave with the stores
			 by subsequent writers.  In turn, this means that
			 we have to clean up when we do not hand over
			 WRLOCKED.
			 Release MO so that another writer that gets
			 WRLOCKED from us can take over our view of
			 __readers.  */
		      unsigned int wf = atomic_exchange_relaxed
			  (&rwlock->__data.__writers_futex, 0);
		      while (w != 0)
			{
			  if (atomic_compare_exchange_weak_release
			      (&rwlock->__data.__writers, &w,
				  w | PTHREAD_RWLOCK_WRHANDOVER))
			    {
			      /* Wake other writers.  */
			      if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0)
				futex_wake (&rwlock->__data.__writers_futex,
					    1, private);
			      return ETIMEDOUT;
			    }
			  /* TODO Back-off.  */
			}
		      /* We still own WRLOCKED and someone else might set
			 a write phase concurrently, so enable waiting
			 again.  Make sure we don't loose the flag that
			 signals whether there are threads waiting on
			 this futex.  */
		      atomic_store_relaxed
			  (&rwlock->__data.__writers_futex, wf);
		    }
		}
	      /* If we timed out and we are not in a write phase, we can
		 just stop being a primary writer.  Otherwise, we just
		 acquire the lock.  */
	      r = atomic_load_relaxed (&rwlock->__data.__readers);
	      if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
		{
		  /* We are about to release WRLOCKED, so we must release
		     __writers_futex too; see the handling of
		     writer--writer hand-over above.  */
		  unsigned int wf = atomic_exchange_relaxed
		      (&rwlock->__data.__writers_futex, 0);
		  while ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
		    {
		      /* While we don't need to make anything from a
			 caller's critical section visible to other
			 threads, we need to ensure that our changes to
			 __writers_futex are properly ordered.
			 Therefore, use release MO to synchronize with
			 subsequent primary writers.  Also wake up any
			 waiting readers as they are waiting because of
			 us.  */
		      if (atomic_compare_exchange_weak_release
			  (&rwlock->__data.__readers, &r,
			   (r ^ PTHREAD_RWLOCK_WRLOCKED)
			   & ~(unsigned int) PTHREAD_RWLOCK_RWAITING))
			{
			  /* Wake other writers.  */
			  if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0)
			    futex_wake (&rwlock->__data.__writers_futex,
				1, private);
			  /* Wake waiting readers.  */
			  if ((r & PTHREAD_RWLOCK_RWAITING) != 0)
			    futex_wake (&rwlock->__data.__readers,
				INT_MAX, private);
			  return ETIMEDOUT;
			}
		    }
		  /* We still own WRLOCKED and someone else might set a
		     write phase concurrently, so enable waiting again.
		     Make sure we don't loose the flag that signals
		     whether there are threads waiting on this futex.  */
		  atomic_store_relaxed (&rwlock->__data.__writers_futex, wf);
		}
	      /* Use the acquire MO fence to mirror the steps taken in the
		 non-timeout case.  Note that the read can happen both
		 in the atomic_load above as well as in the failure case
		 of the CAS operation.  */
	      atomic_thread_fence_acquire ();
	      /* We still need to wait for explicit hand-over, but we must
		 not use futex_wait anymore.  */
	      while ((atomic_load_relaxed
		  (&rwlock->__data.__wrphase_futex)
		   | PTHREAD_RWLOCK_FUTEX_USED)
		  == PTHREAD_RWLOCK_FUTEX_USED)
		{
		  /* TODO Back-off.  */
		}
	      ready = true;
	      break;
	    }
	  /* If we got interrupted (EINTR) or the futex word does not have
	     the expected value (EAGAIN), retry.  */
	}
      /* See pthread_rwlock_rdlock_full.  */
      if (ready)
	break;
      if ((atomic_load_acquire (&rwlock->__data.__readers)
	  & PTHREAD_RWLOCK_WRPHASE) != 0)
	ready = true;
    }

 done:
  atomic_store_relaxed (&rwlock->__data.__cur_writer,
      THREAD_GETMEM (THREAD_SELF, tid));
  return 0;
}
