1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  *
  25  * This file is available under and governed by the GNU General Public
  26  * License version 2 only, as published by the Free Software Foundation.
  27  * However, the following notice accompanied the original version of this
  28  * file:
  29  *
  30  * Written by Doug Lea with assistance from members of JCP JSR-166
  31  * Expert Group and released to the public domain, as explained at
  32  * http://creativecommons.org/publicdomain/zero/1.0/
  33  */
  34 
  35 package java.util.concurrent.locks;
  36 
  37 import java.util.concurrent.ThreadLocalRandom;
  38 import java.util.concurrent.TimeUnit;
  39 import java.util.concurrent.locks.Lock;
  40 import java.util.concurrent.locks.Condition;
  41 import java.util.concurrent.locks.ReadWriteLock;
  42 import java.util.concurrent.locks.LockSupport;
  43 
  44 /**
  45  * A capability-based lock with three modes for controlling read/write
  46  * access.  The state of a StampedLock consists of a version and mode.
  47  * Lock acquisition methods return a stamp that represents and
  48  * controls access with respect to a lock state; "try" versions of
  49  * these methods may instead return the special value zero to
  50  * represent failure to acquire access. Lock release and conversion
  51  * methods require stamps as arguments, and fail if they do not match
  52  * the state of the lock. The three modes are:
  53  *
  54  * <ul>
  55  *
  56  *  <li><b>Writing.</b> Method {@link #writeLock} possibly blocks
  57  *   waiting for exclusive access, returning a stamp that can be used
  58  *   in method {@link #unlockWrite} to release the lock. Untimed and
  59  *   timed versions of {@code tryWriteLock} are also provided. When
  60  *   the lock is held in write mode, no read locks may be obtained,
  61  *   and all optimistic read validations will fail.  </li>
  62  *
  63  *  <li><b>Reading.</b> Method {@link #readLock} possibly blocks
  64  *   waiting for non-exclusive access, returning a stamp that can be
  65  *   used in method {@link #unlockRead} to release the lock. Untimed
  66  *   and timed versions of {@code tryReadLock} are also provided. </li>
  67  *
  68  *  <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
  69  *   returns a non-zero stamp only if the lock is not currently held
  70  *   in write mode. Method {@link #validate} returns true if the lock
  71  *   has not been acquired in write mode since obtaining a given
  72  *   stamp.  This mode can be thought of as an extremely weak version
  73  *   of a read-lock, that can be broken by a writer at any time.  The
  74  *   use of optimistic mode for short read-only code segments often
  75  *   reduces contention and improves throughput.  However, its use is
  76  *   inherently fragile.  Optimistic read sections should only read
  77  *   fields and hold them in local variables for later use after
  78  *   validation. Fields read while in optimistic mode may be wildly
  79  *   inconsistent, so usage applies only when you are familiar enough
  80  *   with data representations to check consistency and/or repeatedly
  81  *   invoke method {@code validate()}.  For example, such steps are
  82  *   typically required when first reading an object or array
  83  *   reference, and then accessing one of its fields, elements or
  84  *   methods. </li>
  85  *
  86  * </ul>
  87  *
  88  * <p>This class also supports methods that conditionally provide
  89  * conversions across the three modes. For example, method {@link
  90  * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
  91  * a valid write stamp if (1) already in writing mode (2) in reading
  92  * mode and there are no other readers or (3) in optimistic mode and
  93  * the lock is available. The forms of these methods are designed to
  94  * help reduce some of the code bloat that otherwise occurs in
  95  * retry-based designs.
  96  *
  97  * <p>StampedLocks are designed for use as internal utilities in the
  98  * development of thread-safe components. Their use relies on
  99  * knowledge of the internal properties of the data, objects, and
 100  * methods they are protecting.  They are not reentrant, so locked
 101  * bodies should not call other unknown methods that may try to
 102  * re-acquire locks (although you may pass a stamp to other methods
 103  * that can use or convert it).  The use of read lock modes relies on
 104  * the associated code sections being side-effect-free.  Unvalidated
 105  * optimistic read sections cannot call methods that are not known to
 106  * tolerate potential inconsistencies.  Stamps use finite
 107  * representations, and are not cryptographically secure (i.e., a
 108  * valid stamp may be guessable). Stamp values may recycle after (no
 109  * sooner than) one year of continuous operation. A stamp held without
 110  * use or validation for longer than this period may fail to validate
 111  * correctly.  StampedLocks are serializable, but always deserialize
 112  * into initial unlocked state, so they are not useful for remote
 113  * locking.
 114  *
 115  * <p>The scheduling policy of StampedLock does not consistently
 116  * prefer readers over writers or vice versa.  All "try" methods are
 117  * best-effort and do not necessarily conform to any scheduling or
 118  * fairness policy. A zero return from any "try" method for acquiring
 119  * or converting locks does not carry any information about the state
 120  * of the lock; a subsequent invocation may succeed.
 121  *
 122  * <p>Because it supports coordinated usage across multiple lock
 123  * modes, this class does not directly implement the {@link Lock} or
 124  * {@link ReadWriteLock} interfaces. However, a StampedLock may be
 125  * viewed {@link #asReadLock()}, {@link #asWriteLock()}, or {@link
 126  * #asReadWriteLock()} in applications requiring only the associated
 127  * set of functionality.
 128  *
 129  * <p><b>Sample Usage.</b> The following illustrates some usage idioms
 130  * in a class that maintains simple two-dimensional points. The sample
 131  * code illustrates some try/catch conventions even though they are
 132  * not strictly needed here because no exceptions can occur in their
 133  * bodies.<br>
 134  *
 135  *  <pre>{@code
 136  * class Point {
 137  *   private double x, y;
 138  *   private final StampedLock sl = new StampedLock();
 139  *
 140  *   void move(double deltaX, double deltaY) { // an exclusively locked method
 141  *     long stamp = sl.writeLock();
 142  *     try {
 143  *       x += deltaX;
 144  *       y += deltaY;
 145  *     } finally {
 146  *       sl.unlockWrite(stamp);
 147  *     }
 148  *   }
 149  *
 150  *   double distanceFromOriginV1() { // A read-only method
 151  *     long stamp;
 152  *     if ((stamp = sl.tryOptimisticRead()) != 0L) { // optimistic
 153  *       double currentX = x;
 154  *       double currentY = y;
 155  *       if (sl.validate(stamp))
 156  *         return Math.sqrt(currentX * currentX + currentY * currentY);
 157  *     }
 158  *     stamp = sl.readLock(); // fall back to read lock
 159  *     try {
 160  *       double currentX = x;
 161  *       double currentY = y;
 162  *         return Math.sqrt(currentX * currentX + currentY * currentY);
 163  *     } finally {
 164  *       sl.unlockRead(stamp);
 165  *     }
 166  *   }
 167  *
 168  *   double distanceFromOriginV2() { // combines code paths
 169  *     double currentX = 0.0, currentY = 0.0;
 170  *     for (long stamp = sl.tryOptimisticRead(); ; stamp = sl.readLock()) {
 171  *       try {
 172  *         currentX = x;
 173  *         currentY = y;
 174  *       } finally {
 175  *         if (sl.tryConvertToOptimisticRead(stamp) != 0L) // unlock or validate
 176  *           break;
 177  *       }
 178  *     }
 179  *     return Math.sqrt(currentX * currentX + currentY * currentY);
 180  *   }
 181  *
 182  *   void moveIfAtOrigin(double newX, double newY) { // upgrade
 183  *     // Could instead start with optimistic, not read mode
 184  *     long stamp = sl.readLock();
 185  *     try {
 186  *       while (x == 0.0 && y == 0.0) {
 187  *         long ws = sl.tryConvertToWriteLock(stamp);
 188  *         if (ws != 0L) {
 189  *           stamp = ws;
 190  *           x = newX;
 191  *           y = newY;
 192  *           break;
 193  *         }
 194  *         else {
 195  *           sl.unlockRead(stamp);
 196  *           stamp = sl.writeLock();
 197  *         }
 198  *       }
 199  *     } finally {
 200  *       sl.unlock(stamp);
 201  *     }
 202  *   }
 203  * }}</pre>
 204  *
 205  * @since 1.8
 206  * @author Doug Lea
 207  */
 208 public class StampedLock implements java.io.Serializable {
 209     /*
 210      * Algorithmic notes:
 211      *
 212      * The design employs elements of Sequence locks
 213      * (as used in linux kernels; see Lameter's
 214      * http://www.lameter.com/gelato2005.pdf
 215      * and elsewhere; see
 216      * Boehm's http://www.hpl.hp.com/techreports/2012/HPL-2012-68.html)
 217      * and Ordered RW locks (see Shirako et al
 218      * http://dl.acm.org/citation.cfm?id=2312015)
 219      *
 220      * Conceptually, the primary state of the lock includes a sequence
 221      * number that is odd when write-locked and even otherwise.
 222      * However, this is offset by a reader count that is non-zero when
 223      * read-locked.  The read count is ignored when validating
 224      * "optimistic" seqlock-reader-style stamps.  Because we must use
 225      * a small finite number of bits (currently 7) for readers, a
 226      * supplementary reader overflow word is used when the number of
 227      * readers exceeds the count field. We do this by treating the max
 228      * reader count value (RBITS) as a spinlock protecting overflow
 229      * updates.
 230      *
 231      * Waiters use a modified form of CLH lock used in
 232      * AbstractQueuedSynchronizer (see its internal documentation for
 233      * a fuller account), where each node is tagged (field mode) as
 234      * either a reader or writer. Sets of waiting readers are grouped
 235      * (linked) under a common node (field cowait) so act as a single
 236      * node with respect to most CLH mechanics.  By virtue of the
 237      * queue structure, wait nodes need not actually carry sequence
 238      * numbers; we know each is greater than its predecessor.  This
 239      * simplifies the scheduling policy to a mainly-FIFO scheme that
 240      * incorporates elements of Phase-Fair locks (see Brandenburg &
 241      * Anderson, especially http://www.cs.unc.edu/~bbb/diss/).  In
 242      * particular, we use the phase-fair anti-barging rule: If an
 243      * incoming reader arrives while read lock is held but there is a
 244      * queued writer, this incoming reader is queued.  (This rule is
 245      * responsible for some of the complexity of method acquireRead,
 246      * but without it, the lock becomes highly unfair.)
 247      *
 248      * These rules apply to threads actually queued. All tryLock forms
 249      * opportunistically try to acquire locks regardless of preference
 250      * rules, and so may "barge" their way in.  Randomized spinning is
 251      * used in the acquire methods to reduce (increasingly expensive)
 252      * context switching while also avoiding sustained memory
 253      * thrashing among many threads.  We limit spins to the head of
 254      * queue. A thread spin-waits up to SPINS times (where each
 255      * iteration decreases spin count with 50% probability) before
 256      * blocking. If, upon wakening it fails to obtain lock, and is
 257      * still (or becomes) the first waiting thread (which indicates
 258      * that some other thread barged and obtained lock), it escalates
 259      * spins (up to MAX_HEAD_SPINS) to reduce the likelihood of
 260      * continually losing to barging threads.
 261      *
 262      * Nearly all of these mechanics are carried out in methods
 263      * acquireWrite and acquireRead, that, as typical of such code,
 264      * sprawl out because actions and retries rely on consistent sets
 265      * of locally cached reads.
 266      *
 267      * As noted in Boehm's paper (above), sequence validation (mainly
 268      * method validate()) requires stricter ordering rules than apply
 269      * to normal volatile reads (of "state").  To force orderings of
 270      * reads before a validation and the validation itself in those
 271      * cases where this is not already forced, we use
 272      * Unsafe.loadFence.
 273      *
 274      * The memory layout keeps lock state and queue pointers together
 275      * (normally on the same cache line). This usually works well for
 276      * read-mostly loads. In most other cases, the natural tendency of
 277      * adaptive-spin CLH locks to reduce memory contention lessens
 278      * motivation to further spread out contended locations, but might
 279      * be subject to future improvements.
 280      */
 281 
 282     private static final long serialVersionUID = -6001602636862214147L;
 283 
 284     /** Number of processors, for spin control */
 285     private static final int NCPU = Runtime.getRuntime().availableProcessors();
 286 
 287     /** Maximum number of retries before blocking on acquisition */
 288     private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
 289 
 290     /** Maximum number of retries before re-blocking */
 291     private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0;
 292 
 293     /** The period for yielding when waiting for overflow spinlock */
 294     private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
 295 
 296     /** The number of bits to use for reader count before overflowing */
 297     private static final int LG_READERS = 7;
 298 
 299     // Values for lock state and stamp operations
 300     private static final long RUNIT = 1L;
 301     private static final long WBIT  = 1L << LG_READERS;
 302     private static final long RBITS = WBIT - 1L;
 303     private static final long RFULL = RBITS - 1L;
 304     private static final long ABITS = RBITS | WBIT;
 305     private static final long SBITS = ~RBITS; // note overlap with ABITS
 306 
 307     // Initial value for lock state; avoid failure value zero
 308     private static final long ORIGIN = WBIT << 1;
 309 
 310     // Special value from cancelled acquire methods so caller can throw IE
 311     private static final long INTERRUPTED = 1L;
 312 
 313     // Values for node status; order matters
 314     private static final int WAITING   = -1;
 315     private static final int CANCELLED =  1;
 316 
 317     // Modes for nodes (int not boolean to allow arithmetic)
 318     private static final int RMODE = 0;
 319     private static final int WMODE = 1;
 320 
 321     /** Wait nodes */
 322     static final class WNode {
 323         volatile WNode prev;
 324         volatile WNode next;
 325         volatile WNode cowait;    // list of linked readers
 326         volatile Thread thread;   // non-null while possibly parked
 327         volatile int status;      // 0, WAITING, or CANCELLED
 328         final int mode;           // RMODE or WMODE
 329         WNode(int m, WNode p) { mode = m; prev = p; }
 330     }
 331 
 332     /** Head of CLH queue */
 333     private transient volatile WNode whead;
 334     /** Tail (last) of CLH queue */
 335     private transient volatile WNode wtail;
 336 
 337     // views
 338     transient ReadLockView readLockView;
 339     transient WriteLockView writeLockView;
 340     transient ReadWriteLockView readWriteLockView;
 341 
 342     /** Lock sequence/state */
 343     private transient volatile long state;
 344     /** extra reader count when state read count saturated */
 345     private transient int readerOverflow;
 346 
 347     /**
 348      * Creates a new lock, initially in unlocked state.
 349      */
 350     public StampedLock() {
 351         state = ORIGIN;
 352     }
 353 
 354     /**
 355      * Exclusively acquires the lock, blocking if necessary
 356      * until available.
 357      *
 358      * @return a stamp that can be used to unlock or convert mode
 359      */
 360     public long writeLock() {
 361         long s, next;  // bypass acquireWrite in fully unlocked case only
 362         return ((((s = state) & ABITS) == 0L &&
 363                  U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
 364                 next : acquireWrite(false, 0L));
 365     }
 366 
 367     /**
 368      * Exclusively acquires the lock if it is immediately available.
 369      *
 370      * @return a stamp that can be used to unlock or convert mode,
 371      * or zero if the lock is not available
 372      */
 373     public long tryWriteLock() {
 374         long s, next;
 375         return ((((s = state) & ABITS) == 0L &&
 376                  U.compareAndSwapLong(this, STATE, s, next = s + WBIT)) ?
 377                 next : 0L);
 378     }
 379 
 380     /**
 381      * Exclusively acquires the lock if it is available within the
 382      * given time and the current thread has not been interrupted.
 383      * Behavior under timeout and interruption matches that specified
 384      * for method {@link Lock#tryLock(long,TimeUnit)}.
 385      *
 386      * @return a stamp that can be used to unlock or convert mode,
 387      * or zero if the lock is not available
 388      * @throws InterruptedException if the current thread is interrupted
 389      * before acquiring the lock
 390      */
 391     public long tryWriteLock(long time, TimeUnit unit)
 392         throws InterruptedException {
 393         long nanos = unit.toNanos(time);
 394         if (!Thread.interrupted()) {
 395             long next, deadline;
 396             if ((next = tryWriteLock()) != 0L)
 397                 return next;
 398             if (nanos <= 0L)
 399                 return 0L;
 400             if ((deadline = System.nanoTime() + nanos) == 0L)
 401                 deadline = 1L;
 402             if ((next = acquireWrite(true, deadline)) != INTERRUPTED)
 403                 return next;
 404         }
 405         throw new InterruptedException();
 406     }
 407 
 408     /**
 409      * Exclusively acquires the lock, blocking if necessary
 410      * until available or the current thread is interrupted.
 411      * Behavior under interruption matches that specified
 412      * for method {@link Lock#lockInterruptibly()}.
 413      *
 414      * @return a stamp that can be used to unlock or convert mode
 415      * @throws InterruptedException if the current thread is interrupted
 416      * before acquiring the lock
 417      */
 418     public long writeLockInterruptibly() throws InterruptedException {
 419         long next;
 420         if (!Thread.interrupted() &&
 421             (next = acquireWrite(true, 0L)) != INTERRUPTED)
 422             return next;
 423         throw new InterruptedException();
 424     }
 425 
 426     /**
 427      * Non-exclusively acquires the lock, blocking if necessary
 428      * until available.
 429      *
 430      * @return a stamp that can be used to unlock or convert mode
 431      */
 432     public long readLock() {
 433         long s, next;  // bypass acquireRead on fully unlocked case only
 434         return ((((s = state) & ABITS) == 0L &&
 435                  U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ?
 436                 next : acquireRead(false, 0L));
 437     }
 438 
 439     /**
 440      * Non-exclusively acquires the lock if it is immediately available.
 441      *
 442      * @return a stamp that can be used to unlock or convert mode,
 443      * or zero if the lock is not available
 444      */
 445     public long tryReadLock() {
 446         for (;;) {
 447             long s, m, next;
 448             if ((m = (s = state) & ABITS) == WBIT)
 449                 return 0L;
 450             else if (m < RFULL) {
 451                 if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
 452                     return next;
 453             }
 454             else if ((next = tryIncReaderOverflow(s)) != 0L)
 455                 return next;
 456         }
 457     }
 458 
 459     /**
 460      * Non-exclusively acquires the lock if it is available within the
 461      * given time and the current thread has not been interrupted.
 462      * Behavior under timeout and interruption matches that specified
 463      * for method {@link Lock#tryLock(long,TimeUnit)}.
 464      *
 465      * @return a stamp that can be used to unlock or convert mode,
 466      * or zero if the lock is not available
 467      * @throws InterruptedException if the current thread is interrupted
 468      * before acquiring the lock
 469      */
 470     public long tryReadLock(long time, TimeUnit unit)
 471         throws InterruptedException {
 472         long s, m, next, deadline;
 473         long nanos = unit.toNanos(time);
 474         if (!Thread.interrupted()) {
 475             if ((m = (s = state) & ABITS) != WBIT) {
 476                 if (m < RFULL) {
 477                     if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
 478                         return next;
 479                 }
 480                 else if ((next = tryIncReaderOverflow(s)) != 0L)
 481                     return next;
 482             }
 483             if (nanos <= 0L)
 484                 return 0L;
 485             if ((deadline = System.nanoTime() + nanos) == 0L)
 486                 deadline = 1L;
 487             if ((next = acquireRead(true, deadline)) != INTERRUPTED)
 488                 return next;
 489         }
 490         throw new InterruptedException();
 491     }
 492 
 493     /**
 494      * Non-exclusively acquires the lock, blocking if necessary
 495      * until available or the current thread is interrupted.
 496      * Behavior under interruption matches that specified
 497      * for method {@link Lock#lockInterruptibly()}.
 498      *
 499      * @return a stamp that can be used to unlock or convert mode
 500      * @throws InterruptedException if the current thread is interrupted
 501      * before acquiring the lock
 502      */
 503     public long readLockInterruptibly() throws InterruptedException {
 504         long next;
 505         if (!Thread.interrupted() &&
 506             (next = acquireRead(true, 0L)) != INTERRUPTED)
 507             return next;
 508         throw new InterruptedException();
 509     }
 510 
 511     /**
 512      * Returns a stamp that can later be validated, or zero
 513      * if exclusively locked.
 514      *
 515      * @return a stamp, or zero if exclusively locked
 516      */
 517     public long tryOptimisticRead() {
 518         long s;
 519         return (((s = state) & WBIT) == 0L) ? (s & SBITS) : 0L;
 520     }
 521 
 522     /**
 523      * Returns true if the lock has not been exclusively acquired
 524      * since issuance of the given stamp. Always returns false if the
 525      * stamp is zero. Always returns true if the stamp represents a
 526      * currently held lock. Invoking this method with a value not
 527      * obtained from {@link #tryOptimisticRead} or a locking method
 528      * for this lock has no defined effect or result.
 529      *
 530      * @return true if the lock has not been exclusively acquired
 531      * since issuance of the given stamp; else false
 532      */
 533     public boolean validate(long stamp) {
 534         U.loadFence();
 535         return (stamp & SBITS) == (state & SBITS);
 536     }
 537 
 538     /**
 539      * If the lock state matches the given stamp, releases the
 540      * exclusive lock.
 541      *
 542      * @param stamp a stamp returned by a write-lock operation
 543      * @throws IllegalMonitorStateException if the stamp does
 544      * not match the current state of this lock
 545      */
 546     public void unlockWrite(long stamp) {
 547         WNode h;
 548         if (state != stamp || (stamp & WBIT) == 0L)
 549             throw new IllegalMonitorStateException();
 550         state = (stamp += WBIT) == 0L ? ORIGIN : stamp;
 551         if ((h = whead) != null && h.status != 0)
 552             release(h);
 553     }
 554 
 555     /**
 556      * If the lock state matches the given stamp, releases the
 557      * non-exclusive lock.
 558      *
 559      * @param stamp a stamp returned by a read-lock operation
 560      * @throws IllegalMonitorStateException if the stamp does
 561      * not match the current state of this lock
 562      */
 563     public void unlockRead(long stamp) {
 564         long s, m; WNode h;
 565         for (;;) {
 566             if (((s = state) & SBITS) != (stamp & SBITS) ||
 567                 (stamp & ABITS) == 0L || (m = s & ABITS) == 0L || m == WBIT)
 568                 throw new IllegalMonitorStateException();
 569             if (m < RFULL) {
 570                 if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
 571                     if (m == RUNIT && (h = whead) != null && h.status != 0)
 572                         release(h);
 573                     break;
 574                 }
 575             }
 576             else if (tryDecReaderOverflow(s) != 0L)
 577                 break;
 578         }
 579     }
 580 
 581     /**
 582      * If the lock state matches the given stamp, releases the
 583      * corresponding mode of the lock.
 584      *
 585      * @param stamp a stamp returned by a lock operation
 586      * @throws IllegalMonitorStateException if the stamp does
 587      * not match the current state of this lock
 588      */
 589     public void unlock(long stamp) {
 590         long a = stamp & ABITS, m, s; WNode h;
 591         while (((s = state) & SBITS) == (stamp & SBITS)) {
 592             if ((m = s & ABITS) == 0L)
 593                 break;
 594             else if (m == WBIT) {
 595                 if (a != m)
 596                     break;
 597                 state = (s += WBIT) == 0L ? ORIGIN : s;
 598                 if ((h = whead) != null && h.status != 0)
 599                     release(h);
 600                 return;
 601             }
 602             else if (a == 0L || a >= WBIT)
 603                 break;
 604             else if (m < RFULL) {
 605                 if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
 606                     if (m == RUNIT && (h = whead) != null && h.status != 0)
 607                         release(h);
 608                     return;
 609                 }
 610             }
 611             else if (tryDecReaderOverflow(s) != 0L)
 612                 return;
 613         }
 614         throw new IllegalMonitorStateException();
 615     }
 616 
 617     /**
 618      * If the lock state matches the given stamp, performs one of
 619      * the following actions. If the stamp represents holding a write
 620      * lock, returns it.  Or, if a read lock, if the write lock is
 621      * available, releases the read lock and returns a write stamp.
 622      * Or, if an optimistic read, returns a write stamp only if
 623      * immediately available. This method returns zero in all other
 624      * cases.
 625      *
 626      * @param stamp a stamp
 627      * @return a valid write stamp, or zero on failure
 628      */
 629     public long tryConvertToWriteLock(long stamp) {
 630         long a = stamp & ABITS, m, s, next;
 631         while (((s = state) & SBITS) == (stamp & SBITS)) {
 632             if ((m = s & ABITS) == 0L) {
 633                 if (a != 0L)
 634                     break;
 635                 if (U.compareAndSwapLong(this, STATE, s, next = s + WBIT))
 636                     return next;
 637             }
 638             else if (m == WBIT) {
 639                 if (a != m)
 640                     break;
 641                 return stamp;
 642             }
 643             else if (m == RUNIT && a != 0L) {
 644                 if (U.compareAndSwapLong(this, STATE, s,
 645                                          next = s - RUNIT + WBIT))
 646                     return next;
 647             }
 648             else
 649                 break;
 650         }
 651         return 0L;
 652     }
 653 
 654     /**
 655      * If the lock state matches the given stamp, performs one of
 656      * the following actions. If the stamp represents holding a write
 657      * lock, releases it and obtains a read lock.  Or, if a read lock,
 658      * returns it. Or, if an optimistic read, acquires a read lock and
 659      * returns a read stamp only if immediately available. This method
 660      * returns zero in all other cases.
 661      *
 662      * @param stamp a stamp
 663      * @return a valid read stamp, or zero on failure
 664      */
 665     public long tryConvertToReadLock(long stamp) {
 666         long a = stamp & ABITS, m, s, next; WNode h;
 667         while (((s = state) & SBITS) == (stamp & SBITS)) {
 668             if ((m = s & ABITS) == 0L) {
 669                 if (a != 0L)
 670                     break;
 671                 else if (m < RFULL) {
 672                     if (U.compareAndSwapLong(this, STATE, s, next = s + RUNIT))
 673                         return next;
 674                 }
 675                 else if ((next = tryIncReaderOverflow(s)) != 0L)
 676                     return next;
 677             }
 678             else if (m == WBIT) {
 679                 if (a != m)
 680                     break;
 681                 state = next = s + (WBIT + RUNIT);
 682                 if ((h = whead) != null && h.status != 0)
 683                     release(h);
 684                 return next;
 685             }
 686             else if (a != 0L && a < WBIT)
 687                 return stamp;
 688             else
 689                 break;
 690         }
 691         return 0L;
 692     }
 693 
 694     /**
 695      * If the lock state matches the given stamp then, if the stamp
 696      * represents holding a lock, releases it and returns an
 697      * observation stamp.  Or, if an optimistic read, returns it if
 698      * validated. This method returns zero in all other cases, and so
 699      * may be useful as a form of "tryUnlock".
 700      *
 701      * @param stamp a stamp
 702      * @return a valid optimistic read stamp, or zero on failure
 703      */
 704     public long tryConvertToOptimisticRead(long stamp) {
 705         long a = stamp & ABITS, m, s, next; WNode h;
 706         for (;;) {
 707             U.loadFence();
 708             if (((s = state) & SBITS) != (stamp & SBITS))
 709                 break;
 710             if ((m = s & ABITS) == 0L) {
 711                 if (a != 0L)
 712                     break;
 713                 return s;
 714             }
 715             else if (m == WBIT) {
 716                 if (a != m)
 717                     break;
 718                 state = next = (s += WBIT) == 0L ? ORIGIN : s;
 719                 if ((h = whead) != null && h.status != 0)
 720                     release(h);
 721                 return next;
 722             }
 723             else if (a == 0L || a >= WBIT)
 724                 break;
 725             else if (m < RFULL) {
 726                 if (U.compareAndSwapLong(this, STATE, s, next = s - RUNIT)) {
 727                     if (m == RUNIT && (h = whead) != null && h.status != 0)
 728                         release(h);
 729                     return next & SBITS;
 730                 }
 731             }
 732             else if ((next = tryDecReaderOverflow(s)) != 0L)
 733                 return next & SBITS;
 734         }
 735         return 0L;
 736     }
 737 
 738     /**
 739      * Releases the write lock if it is held, without requiring a
 740      * stamp value. This method may be useful for recovery after
 741      * errors.
 742      *
 743      * @return true if the lock was held, else false
 744      */
 745     public boolean tryUnlockWrite() {
 746         long s; WNode h;
 747         if (((s = state) & WBIT) != 0L) {
 748             state = (s += WBIT) == 0L ? ORIGIN : s;
 749             if ((h = whead) != null && h.status != 0)
 750                 release(h);
 751             return true;
 752         }
 753         return false;
 754     }
 755 
 756     /**
 757      * Releases one hold of the read lock if it is held, without
 758      * requiring a stamp value. This method may be useful for recovery
 759      * after errors.
 760      *
 761      * @return true if the read lock was held, else false
 762      */
 763     public boolean tryUnlockRead() {
 764         long s, m; WNode h;
 765         while ((m = (s = state) & ABITS) != 0L && m < WBIT) {
 766             if (m < RFULL) {
 767                 if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
 768                     if (m == RUNIT && (h = whead) != null && h.status != 0)
 769                         release(h);
 770                     return true;
 771                 }
 772             }
 773             else if (tryDecReaderOverflow(s) != 0L)
 774                 return true;
 775         }
 776         return false;
 777     }
 778 
 779     /**
 780      * Returns true if the lock is currently held exclusively.
 781      *
 782      * @return true if the lock is currently held exclusively
 783      */
 784     public boolean isWriteLocked() {
 785         return (state & WBIT) != 0L;
 786     }
 787 
 788     /**
 789      * Returns true if the lock is currently held non-exclusively.
 790      *
 791      * @return true if the lock is currently held non-exclusively
 792      */
 793     public boolean isReadLocked() {
 794         return (state & RBITS) != 0L;
 795     }
 796 
 797     private void readObject(java.io.ObjectInputStream s)
 798         throws java.io.IOException, ClassNotFoundException {
 799         s.defaultReadObject();
 800         state = ORIGIN; // reset to unlocked state
 801     }
 802 
 803     /**
 804      * Returns a plain {@link Lock} view of this StampedLock in which
 805      * the {@link Lock#lock} method is mapped to {@link #readLock},
 806      * and similarly for other methods. The returned Lock does not
 807      * support a {@link Condition}; method {@link
 808      * Lock#newCondition()} throws {@code
 809      * UnsupportedOperationException}.
 810      *
 811      * @return the lock
 812      */
 813     public Lock asReadLock() {
 814         ReadLockView v;
 815         return ((v = readLockView) != null ? v :
 816                 (readLockView = new ReadLockView()));
 817     }
 818 
 819     /**
 820      * Returns a plain {@link Lock} view of this StampedLock in which
 821      * the {@link Lock#lock} method is mapped to {@link #writeLock},
 822      * and similarly for other methods. The returned Lock does not
 823      * support a {@link Condition}; method {@link
 824      * Lock#newCondition()} throws {@code
 825      * UnsupportedOperationException}.
 826      *
 827      * @return the lock
 828      */
 829     public Lock asWriteLock() {
 830         WriteLockView v;
 831         return ((v = writeLockView) != null ? v :
 832                 (writeLockView = new WriteLockView()));
 833     }
 834 
 835     /**
 836      * Returns a {@link ReadWriteLock} view of this StampedLock in
 837      * which the {@link ReadWriteLock#readLock()} method is mapped to
 838      * {@link #asReadLock()}, and {@link ReadWriteLock#writeLock()} to
 839      * {@link #asWriteLock()}.
 840      *
 841      * @return the lock
 842      */
 843     public ReadWriteLock asReadWriteLock() {
 844         ReadWriteLockView v;
 845         return ((v = readWriteLockView) != null ? v :
 846                 (readWriteLockView = new ReadWriteLockView()));
 847     }
 848 
 849     // view classes
 850 
 851     final class ReadLockView implements Lock {
 852         public void lock() { readLock(); }
 853         public void lockInterruptibly() throws InterruptedException {
 854             readLockInterruptibly();
 855         }
 856         public boolean tryLock() { return tryReadLock() != 0L; }
 857         public boolean tryLock(long time, TimeUnit unit)
 858             throws InterruptedException {
 859             return tryReadLock(time, unit) != 0L;
 860         }
 861         public void unlock() { unstampedUnlockRead(); }
 862         public Condition newCondition() {
 863             throw new UnsupportedOperationException();
 864         }
 865     }
 866 
 867     final class WriteLockView implements Lock {
 868         public void lock() { writeLock(); }
 869         public void lockInterruptibly() throws InterruptedException {
 870             writeLockInterruptibly();
 871         }
 872         public boolean tryLock() { return tryWriteLock() != 0L; }
 873         public boolean tryLock(long time, TimeUnit unit)
 874             throws InterruptedException {
 875             return tryWriteLock(time, unit) != 0L;
 876         }
 877         public void unlock() { unstampedUnlockWrite(); }
 878         public Condition newCondition() {
 879             throw new UnsupportedOperationException();
 880         }
 881     }
 882 
 883     final class ReadWriteLockView implements ReadWriteLock {
 884         public Lock readLock() { return asReadLock(); }
 885         public Lock writeLock() { return asWriteLock(); }
 886     }
 887 
 888     // Unlock methods without stamp argument checks for view classes.
 889     // Needed because view-class lock methods throw away stamps.
 890 
 891     final void unstampedUnlockWrite() {
 892         WNode h; long s;
 893         if (((s = state) & WBIT) == 0L)
 894             throw new IllegalMonitorStateException();
 895         state = (s += WBIT) == 0L ? ORIGIN : s;
 896         if ((h = whead) != null && h.status != 0)
 897             release(h);
 898     }
 899 
 900     final void unstampedUnlockRead() {
 901         for (;;) {
 902             long s, m; WNode h;
 903             if ((m = (s = state) & ABITS) == 0L || m >= WBIT)
 904                 throw new IllegalMonitorStateException();
 905             else if (m < RFULL) {
 906                 if (U.compareAndSwapLong(this, STATE, s, s - RUNIT)) {
 907                     if (m == RUNIT && (h = whead) != null && h.status != 0)
 908                         release(h);
 909                     break;
 910                 }
 911             }
 912             else if (tryDecReaderOverflow(s) != 0L)
 913                 break;
 914         }
 915     }
 916 
 917     // internals
 918 
 919     /**
 920      * Tries to increment readerOverflow by first setting state
 921      * access bits value to RBITS, indicating hold of spinlock,
 922      * then updating, then releasing.
 923      *
 924      * @param s, assumed that (s & ABITS) >= RFULL
 925      * @return new stamp on success, else zero
 926      */
 927     private long tryIncReaderOverflow(long s) {
 928         if ((s & ABITS) == RFULL) {
 929             if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
 930                 ++readerOverflow;
 931                 state = s;
 932                 return s;
 933             }
 934         }
 935         else if ((ThreadLocalRandom.current().nextInt() &
 936                   OVERFLOW_YIELD_RATE) == 0)
 937             Thread.yield();
 938         return 0L;
 939     }
 940 
 941     /**
 942      * Tries to decrement readerOverflow.
 943      *
 944      * @param s, assumed that (s & ABITS) >= RFULL
 945      * @return new stamp on success, else zero
 946      */
 947     private long tryDecReaderOverflow(long s) {
 948         if ((s & ABITS) == RFULL) {
 949             if (U.compareAndSwapLong(this, STATE, s, s | RBITS)) {
 950                 int r; long next;
 951                 if ((r = readerOverflow) > 0) {
 952                     readerOverflow = r - 1;
 953                     next = s;
 954                 }
 955                 else
 956                     next = s - RUNIT;
 957                  state = next;
 958                  return next;
 959             }
 960         }
 961         else if ((ThreadLocalRandom.current().nextInt() &
 962                   OVERFLOW_YIELD_RATE) == 0)
 963             Thread.yield();
 964         return 0L;
 965     }
 966 
 967     /*
 968      * Wakes up the successor of h (normally whead). This is normally
 969      * just h.next, but may require traversal from wtail if next
 970      * pointers are lagging. This may fail to wake up an acquiring
 971      * thread when one or more have been cancelled, but the cancel
 972      * methods themselves provide extra safeguards to ensure liveness.
 973      */
 974     private void release(WNode h) {
 975         if (h != null) {
 976             WNode q; Thread w;
 977             U.compareAndSwapInt(h, WSTATUS, WAITING, 0);
 978             if ((q = h.next) == null || q.status == CANCELLED) {
 979                 for (WNode t = wtail; t != null && t != h; t = t.prev)
 980                     if (t.status <= 0)
 981                         q = t;
 982             }
 983             if (q != null) {
 984                 for (WNode r = q;;) {  // release co-waiters too
 985                     if ((w = r.thread) != null) {
 986                         r.thread = null;
 987                         U.unpark(w);
 988                     }
 989                     if ((r = q.cowait) == null)
 990                         break;
 991                     U.compareAndSwapObject(q, WCOWAIT, r, r.cowait);
 992                 }
 993             }
 994         }
 995     }
 996 
 997     /**
 998      * See above for explanation.
 999      *
1000      * @param interruptible true if should check interrupts and if so
1001      * return INTERRUPTED
1002      * @param deadline if nonzero, the System.nanoTime value to timeout
1003      * at (and return zero)
1004      * @return next state, or INTERRUPTED
1005      */
1006     private long acquireWrite(boolean interruptible, long deadline) {
1007         WNode node = null, p;
1008         for (int spins = -1;;) { // spin while enqueuing
1009             long s, ns;
1010             if (((s = state) & ABITS) == 0L) {
1011                 if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT))
1012                     return ns;
1013             }
1014             else if (spins > 0) {
1015                 if (ThreadLocalRandom.current().nextInt() >= 0)
1016                     --spins;
1017             }
1018             else if ((p = wtail) == null) { // initialize queue
1019                 WNode h = new WNode(WMODE, null);
1020                 if (U.compareAndSwapObject(this, WHEAD, null, h))
1021                     wtail = h;
1022             }
1023             else if (spins < 0)
1024                 spins = (p == whead) ? SPINS : 0;
1025             else if (node == null)
1026                 node = new WNode(WMODE, p);
1027             else if (node.prev != p)
1028                 node.prev = p;
1029             else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
1030                 p.next = node;
1031                 break;
1032             }
1033         }
1034 
1035         for (int spins = SPINS;;) {
1036             WNode np, pp; int ps; long s, ns; Thread w;
1037             while ((np = node.prev) != p && np != null)
1038                 (p = np).next = node;   // stale
1039             if (whead == p) {
1040                 for (int k = spins;;) { // spin at head
1041                     if (((s = state) & ABITS) == 0L) {
1042                         if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) {
1043                             whead = node;
1044                             node.prev = null;
1045                             return ns;
1046                         }
1047                     }
1048                     else if (ThreadLocalRandom.current().nextInt() >= 0 &&
1049                              --k <= 0)
1050                         break;
1051                 }
1052                 if (spins < MAX_HEAD_SPINS)
1053                     spins <<= 1;
1054             }
1055             if ((ps = p.status) == 0)
1056                 U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
1057             else if (ps == CANCELLED) {
1058                 if ((pp = p.prev) != null) {
1059                     node.prev = pp;
1060                     pp.next = node;
1061                 }
1062             }
1063             else {
1064                 long time; // 0 argument to park means no timeout
1065                 if (deadline == 0L)
1066                     time = 0L;
1067                 else if ((time = deadline - System.nanoTime()) <= 0L)
1068                     return cancelWaiter(node, node, false);
1069                 node.thread = Thread.currentThread();
1070                 if (node.prev == p && p.status == WAITING && // recheck
1071                     (p != whead || (state & ABITS) != 0L))
1072                     U.park(false, time);
1073                 node.thread = null;
1074                 if (interruptible && Thread.interrupted())
1075                     return cancelWaiter(node, node, true);
1076             }
1077         }
1078     }
1079 
1080     /**
1081      * See above for explanation.
1082      *
1083      * @param interruptible true if should check interrupts and if so
1084      * return INTERRUPTED
1085      * @param deadline if nonzero, the System.nanoTime value to timeout
1086      * at (and return zero)
1087      * @return next state, or INTERRUPTED
1088      */
1089     private long acquireRead(boolean interruptible, long deadline) {
1090         WNode node = null, group = null, p;
1091         for (int spins = -1;;) {
1092             for (;;) {
1093                 long s, m, ns; WNode h, q; Thread w; // anti-barging guard
1094                 if (group == null && (h = whead) != null &&
1095                     (q = h.next) != null && q.mode != RMODE)
1096                     break;
1097                 if ((m = (s = state) & ABITS) < RFULL ?
1098                     U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
1099                     (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
1100                     if (group != null) {  // help release others
1101                         for (WNode r = group;;) {
1102                             if ((w = r.thread) != null) {
1103                                 r.thread = null;
1104                                 U.unpark(w);
1105                             }
1106                             if ((r = group.cowait) == null)
1107                                 break;
1108                             U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
1109                         }
1110                     }
1111                     return ns;
1112                 }
1113                 if (m >= WBIT)
1114                     break;
1115             }
1116             if (spins > 0) {
1117                 if (ThreadLocalRandom.current().nextInt() >= 0)
1118                     --spins;
1119             }
1120             else if ((p = wtail) == null) {
1121                 WNode h = new WNode(WMODE, null);
1122                 if (U.compareAndSwapObject(this, WHEAD, null, h))
1123                     wtail = h;
1124             }
1125             else if (spins < 0)
1126                 spins = (p == whead) ? SPINS : 0;
1127             else if (node == null)
1128                 node = new WNode(WMODE, p);
1129             else if (node.prev != p)
1130                 node.prev = p;
1131             else if (p.mode == RMODE && p != whead) {
1132                 WNode pp = p.prev;  // become co-waiter with group p
1133                 if (pp != null && p == wtail &&
1134                     U.compareAndSwapObject(p, WCOWAIT,
1135                                            node.cowait = p.cowait, node)) {
1136                     node.thread = Thread.currentThread();
1137                     for (long time;;) {
1138                         if (interruptible && Thread.interrupted())
1139                             return cancelWaiter(node, p, true);
1140                         if (deadline == 0L)
1141                             time = 0L;
1142                         else if ((time = deadline - System.nanoTime()) <= 0L)
1143                             return cancelWaiter(node, p, false);
1144                         if (node.thread == null)
1145                             break;
1146                         if (p.prev != pp || p.status == CANCELLED ||
1147                             p == whead || p.prev != pp) {
1148                             node.thread = null;
1149                             break;
1150                         }
1151                         if (node.thread == null) // must recheck
1152                             break;
1153                         U.park(false, time);
1154                     }
1155                     group = p;
1156                 }
1157                 node = null; // throw away
1158             }
1159             else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
1160                 p.next = node;
1161                 break;
1162             }
1163         }
1164 
1165         for (int spins = SPINS;;) {
1166             WNode np, pp, r; int ps; long m, s, ns; Thread w;
1167             while ((np = node.prev) != p && np != null)
1168                 (p = np).next = node;
1169             if (whead == p) {
1170                 for (int k = spins;;) {
1171                     if ((m = (s = state) & ABITS) != WBIT) {
1172                         if (m < RFULL ?
1173                             U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT):
1174                             (ns = tryIncReaderOverflow(s)) != 0L) {
1175                             whead = node;
1176                             node.prev = null;
1177                             while ((r = node.cowait) != null) {
1178                                 if (U.compareAndSwapObject(node, WCOWAIT,
1179                                                            r, r.cowait) &&
1180                                     (w = r.thread) != null) {
1181                                     r.thread = null;
1182                                     U.unpark(w); // release co-waiter
1183                                 }
1184                             }
1185                             return ns;
1186                         }
1187                     }
1188                     else if (ThreadLocalRandom.current().nextInt() >= 0 &&
1189                              --k <= 0)
1190                         break;
1191                 }
1192                 if (spins < MAX_HEAD_SPINS)
1193                     spins <<= 1;
1194             }
1195             if ((ps = p.status) == 0)
1196                 U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
1197             else if (ps == CANCELLED) {
1198                 if ((pp = p.prev) != null) {
1199                     node.prev = pp;
1200                     pp.next = node;
1201                 }
1202             }
1203             else {
1204                 long time;
1205                 if (deadline == 0L)
1206                     time = 0L;
1207                 else if ((time = deadline - System.nanoTime()) <= 0L)
1208                     return cancelWaiter(node, node, false);
1209                 node.thread = Thread.currentThread();
1210                 if (node.prev == p && p.status == WAITING &&
1211                     (p != whead || (state & ABITS) != WBIT))
1212                     U.park(false, time);
1213                 node.thread = null;
1214                 if (interruptible && Thread.interrupted())
1215                     return cancelWaiter(node, node, true);
1216             }
1217         }
1218     }
1219 
1220     /**
1221      * If node non-null, forces cancel status and unsplices it from
1222      * queue if possible and wakes up any cowaiters (of the node, or
1223      * group, as applicable), and in any case helps release current
1224      * first waiter if lock is free. (Calling with null arguments
1225      * serves as a conditional form of release, which is not currently
1226      * needed but may be needed under possible future cancellation
1227      * policies). This is a variant of cancellation methods in
1228      * AbstractQueuedSynchronizer (see its detailed explanation in AQS
1229      * internal documentation).
1230      *
1231      * @param node if nonnull, the waiter
1232      * @param group, either node or the group node is cowaiting with
1233      * @param interrupted if already interrupted
1234      * @return INTERRUPTED if interrupted or Thread.interrupted, else zero
1235      */
1236     private long cancelWaiter(WNode node, WNode group, boolean interrupted) {
1237         if (node != null && group != null) {
1238             Thread w;
1239             node.status = CANCELLED;
1240             node.thread = null;
1241             // unsplice cancelled nodes from group
1242             for (WNode p = group, q; (q = p.cowait) != null;) {
1243                 if (q.status == CANCELLED)
1244                     U.compareAndSwapObject(p, WNEXT, q, q.next);
1245                 else
1246                     p = q;
1247             }
1248             if (group == node) {
1249                 WNode r; // detach and wake up uncancelled co-waiters
1250                 while ((r = node.cowait) != null) {
1251                     if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) &&
1252                         (w = r.thread) != null) {
1253                         r.thread = null;
1254                         U.unpark(w);
1255                     }
1256                 }
1257                 for (WNode pred = node.prev; pred != null; ) { // unsplice
1258                     WNode succ, pp;        // find valid successor
1259                     while ((succ = node.next) == null ||
1260                            succ.status == CANCELLED) {
1261                         WNode q = null;    // find successor the slow way
1262                         for (WNode t = wtail; t != null && t != node; t = t.prev)
1263                             if (t.status != CANCELLED)
1264                                 q = t;     // don't link if succ cancelled
1265                         if (succ == q ||   // ensure accurate successor
1266                             U.compareAndSwapObject(node, WNEXT,
1267                                                    succ, succ = q)) {
1268                             if (succ == null && node == wtail)
1269                                 U.compareAndSwapObject(this, WTAIL, node, pred);
1270                             break;
1271                         }
1272                     }
1273                     if (pred.next == node) // unsplice pred link
1274                         U.compareAndSwapObject(pred, WNEXT, node, succ);
1275                     if (succ != null && (w = succ.thread) != null) {
1276                         succ.thread = null;
1277                         U.unpark(w);       // wake up succ to observe new pred
1278                     }
1279                     if (pred.status != CANCELLED || (pp = pred.prev) == null)
1280                         break;
1281                     node.prev = pp;        // repeat if new pred wrong/cancelled
1282                     U.compareAndSwapObject(pp, WNEXT, pred, succ);
1283                     pred = pp;
1284                 }
1285             }
1286         }
1287         WNode h; // Possibly release first waiter
1288         while ((h = whead) != null) {
1289             long s; WNode q; // similar to release() but check eligibility
1290             if ((q = h.next) == null || q.status == CANCELLED) {
1291                 for (WNode t = wtail; t != null && t != h; t = t.prev)
1292                     if (t.status <= 0)
1293                         q = t;
1294             }
1295             if (h == whead) {
1296                 if (q != null && h.status == 0 &&
1297                     ((s = state) & ABITS) != WBIT && // waiter is eligible
1298                     (s == 0L || q.mode == RMODE))
1299                     release(h);
1300                 break;
1301             }
1302         }
1303         return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
1304     }
1305 
1306     // Unsafe mechanics
1307     private static final sun.misc.Unsafe U;
1308     private static final long STATE;
1309     private static final long WHEAD;
1310     private static final long WTAIL;
1311     private static final long WNEXT;
1312     private static final long WSTATUS;
1313     private static final long WCOWAIT;
1314 
1315     static {
1316         try {
1317             U = sun.misc.Unsafe.getUnsafe();
1318             Class<?> k = StampedLock.class;
1319             Class<?> wk = WNode.class;
1320             STATE = U.objectFieldOffset
1321                 (k.getDeclaredField("state"));
1322             WHEAD = U.objectFieldOffset
1323                 (k.getDeclaredField("whead"));
1324             WTAIL = U.objectFieldOffset
1325                 (k.getDeclaredField("wtail"));
1326             WSTATUS = U.objectFieldOffset
1327                 (wk.getDeclaredField("status"));
1328             WNEXT = U.objectFieldOffset
1329                 (wk.getDeclaredField("next"));
1330             WCOWAIT = U.objectFieldOffset
1331                 (wk.getDeclaredField("cowait"));
1332 
1333         } catch (Exception e) {
1334             throw new Error(e);
1335         }
1336     }
1337 }