ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/StampedLock.java
(Generate patch)

Comparing jsr166/src/jsr166e/StampedLock.java (file contents):
Revision 1.2 by jsr166, Fri Oct 12 16:22:40 2012 UTC vs.
Revision 1.6 by dl, Fri Oct 12 17:35:29 2012 UTC

# Line 26 | Line 26 | import java.util.concurrent.TimeUnit;
26   *   in method {@link #unlockWrite} to release the lock. Untimed and
27   *   timed versions of {@code tryWriteLock} are also provided. When
28   *   the lock is held in write mode, no read locks may be obtained,
29 < *   and all observer validations will fail.  </li>
29 > *   and all optimistic read validations will fail.  </li>
30   *
31   *  <li><b>Reading.</b> Method {@link #readLock} possibly blocks
32   *   waiting for non-exclusive access, returning a stamp that can be
# Line 87 | Line 87 | import java.util.concurrent.TimeUnit;
87   *
88   *  <pre>{@code
89   * class Point {
90 < *   private volatile double x, y;
90 > *   private double x, y;
91   *   private final StampedLock sl = new StampedLock();
92   *
93   *   void move(double deltaX, double deltaY) { // an exclusively locked method
# Line 177 | Line 177 | public class StampedLock implements java
177       * read-locked.  The read count is ignored when validating
178       * "optimistic" seqlock-reader-style stamps.  Because we must use
179       * a small finite number of bits (currently 7) for readers, a
180 <     * supplementatry reader overflow word is used when then number of
180 >     * supplementary reader overflow word is used when then number of
181       * readers exceeds the count field. We do this by treating the max
182       * reader count value (RBITS) as a spinlock protecting overflow
183       * updates.
# Line 235 | Line 235 | public class StampedLock implements java
235      private static final int NCPU = Runtime.getRuntime().availableProcessors();
236  
237      /** Maximum number of retries before blocking on acquisition */
238 <    private static final int SPINS = NCPU > 1 ? 1 << 6 : 1;
238 >    private static final int SPINS = (NCPU > 1) ? 1 << 6 : 1;
239  
240 <    /** Maximum number of retries before re-blocking on write lock */
241 <    private static final int MAX_HEAD_SPINS = NCPU > 1 ? 1 << 12 : 1;
240 >    /** Maximum number of retries before re-blocking */
241 >    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 1;
242  
243      /** The period for yielding when waiting for overflow spinlock */
244      private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
# Line 303 | Line 303 | public class StampedLock implements java
303       * Exclusively acquires the lock, blocking if necessary
304       * until available.
305       *
306 <     * @return a stamp that can be used to unlock or convert mode.
306 >     * @return a stamp that can be used to unlock or convert mode
307       */
308      public long writeLock() {
309          long s, next;
# Line 329 | Line 329 | public class StampedLock implements java
329  
330      /**
331       * Exclusively acquires the lock if it is available within the
332 <     * given time and the current thread has not been interrupted
332 >     * given time and the current thread has not been interrupted.
333       *
334       * @return a stamp that can be used to unlock or convert mode,
335 <     * or zero if the lock is not available.
335 >     * or zero if the lock is not available
336       * @throws InterruptedException if the current thread is interrupted
337 <     * before acquiring the lock.
337 >     * before acquiring the lock
338       */
339      public long tryWriteLock(long time, TimeUnit unit)
340          throws InterruptedException {
341 <        long nanos =  unit.toNanos(time);
341 >        long nanos = unit.toNanos(time);
342          if (!Thread.interrupted()) {
343              long s, next, deadline;
344              if (((s = state) & ABITS) == 0L &&
# Line 358 | Line 358 | public class StampedLock implements java
358       * Exclusively acquires the lock, blocking if necessary
359       * until available or the current thread is interrupted.
360       *
361 <     * @return a stamp that can be used to unlock or convert mode.
361 >     * @return a stamp that can be used to unlock or convert mode
362       * @throws InterruptedException if the current thread is interrupted
363 <     * before acquiring the lock.
363 >     * before acquiring the lock
364       */
365      public long writeLockInterruptibly() throws InterruptedException {
366          if (!Thread.interrupted()) {
# Line 378 | Line 378 | public class StampedLock implements java
378       * Non-exclusively acquires the lock, blocking if necessary
379       * until available.
380       *
381 <     * @return a stamp that can be used to unlock or convert mode.
381 >     * @return a stamp that can be used to unlock or convert mode
382       */
383      public long readLock() {
384          for (;;) {
# Line 401 | Line 401 | public class StampedLock implements java
401       * Non-exclusively acquires the lock if it is immediately available.
402       *
403       * @return a stamp that can be used to unlock or convert mode,
404 <     * or zero if the lock is not available.
404 >     * or zero if the lock is not available
405       */
406      public long tryReadLock() {
407          for (;;) {
# Line 419 | Line 419 | public class StampedLock implements java
419  
420      /**
421       * Non-exclusively acquires the lock if it is available within the
422 <     * given time and the current thread has not been interrupted
422 >     * given time and the current thread has not been interrupted.
423       *
424       * @return a stamp that can be used to unlock or convert mode,
425 <     * or zero if the lock is not available.
425 >     * or zero if the lock is not available
426       * @throws InterruptedException if the current thread is interrupted
427 <     * before acquiring the lock.
427 >     * before acquiring the lock
428       */
429      public long tryReadLock(long time, TimeUnit unit)
430          throws InterruptedException {
# Line 457 | Line 457 | public class StampedLock implements java
457       * Non-exclusively acquires the lock, blocking if necessary
458       * until available or the current thread is interrupted.
459       *
460 <     * @return a stamp that can be used to unlock or convert mode.
460 >     * @return a stamp that can be used to unlock or convert mode
461       * @throws InterruptedException if the current thread is interrupted
462 <     * before acquiring the lock.
462 >     * before acquiring the lock
463       */
464      public long readLockInterruptibly() throws InterruptedException {
465          if (!Thread.interrupted()) {
# Line 512 | Line 512 | public class StampedLock implements java
512       *
513       * @param stamp a stamp returned by a write-lock operation
514       * @throws IllegalMonitorStateException if the stamp does
515 <     * not match the current state of this lock.
515 >     * not match the current state of this lock
516       */
517      public void unlockWrite(long stamp) {
518          if (state != stamp || (stamp & WBIT) == 0L)
# Line 527 | Line 527 | public class StampedLock implements java
527       *
528       * @param stamp a stamp returned by a read-lock operation
529       * @throws IllegalMonitorStateException if the stamp does
530 <     * not match the current state of this lock.
530 >     * not match the current state of this lock
531       */
532      public void unlockRead(long stamp) {
533          long s, m;
# Line 557 | Line 557 | public class StampedLock implements java
557       *
558       * @param stamp a stamp returned by a lock operation
559       * @throws IllegalMonitorStateException if the stamp does
560 <     * not match the current state of this lock.
560 >     * not match the current state of this lock
561       */
562      public void unlock(long stamp) {
563          long a = stamp & ABITS, m, s;
# Line 707 | Line 707 | public class StampedLock implements java
707       * stamp value. This method may be useful for recovery after
708       * errors.
709       *
710 <     * @return true if the lock was held, else false.
710 >     * @return true if the lock was held, else false
711       */
712      public boolean tryUnlockWrite() {
713          long s;
# Line 724 | Line 724 | public class StampedLock implements java
724       * requiring a stamp value. This method may be useful for recovery
725       * after errors.
726       *
727 <     * @return true if the read lock was held, else false.
727 >     * @return true if the read lock was held, else false
728       */
729      public boolean tryUnlockRead() {
730          long s, m;
# Line 773 | Line 773 | public class StampedLock implements java
773       * Tries to increment readerOverflow by first setting state
774       * access bits value to RBITS, indicating hold of spinlock,
775       * then updating, then releasing.
776 +     *
777       * @param stamp, assumed that (stamp & ABITS) >= RFULL
778       * @return new stamp on success, else zero
779       */
# Line 792 | Line 793 | public class StampedLock implements java
793  
794      /**
795       * Tries to decrement readerOverflow.
796 +     *
797       * @param stamp, assumed that (stamp & ABITS) >= RFULL
798       * @return new stamp on success, else zero
799       */
# Line 911 | Line 913 | public class StampedLock implements java
913  
914      /**
915       * Possibly spins trying to obtain write lock, then enqueues and
916 <     * blocks while not head of write queue or cannot aquire lock,
916 >     * blocks while not head of write queue or cannot acquire lock,
917       * possibly spinning when at head; cancelling on timeout or
918       * interrupt.
919       *
920       * @param interruptible true if should check interrupts and if so
921       * return INTERRUPTED
922       * @param deadline if nonzero, the System.nanoTime value to timeout
923 <     * at (and return zero).
923 >     * at (and return zero)
924       */
925      private long awaitWrite(boolean interruptible, long deadline) {
926          WNode node = null;
# Line 1019 | Line 1021 | public class StampedLock implements java
1021              }
1022          }
1023          writerPrefSignal();
1024 <        return (interrupted || Thread.interrupted())? INTERRUPTED : 0L;
1024 >        return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
1025      }
1026  
1027 <    /*
1027 >    /**
1028       * Waits for read lock or timeout or interrupt. The form of
1029       * awaitRead differs from awaitWrite mainly because it must
1030       * restart (with a new wait node) if the thread was unqueued and
# Line 1101 | Line 1103 | public class StampedLock implements java
1103      /**
1104       * If node non-null, forces cancel status and unsplices from queue
1105       * if possible, by traversing entire queue looking for cancelled
1106 <     * nodes, cleaning out all at head, but stopping upon first
1105 <     * encounter otherwise.
1106 >     * nodes.
1107       */
1108      private long cancelReader(RNode node, boolean interrupted) {
1109          Thread w;
# Line 1117 | Line 1118 | public class StampedLock implements java
1118                      }
1119                      else {
1120                          U.compareAndSwapObject(pred, RNEXT, p, q);
1121 <                        break;
1121 >                        p = pred.next;
1122                      }
1123                  }
1124                  else {
# Line 1127 | Line 1128 | public class StampedLock implements java
1128              }
1129          }
1130          readerPrefSignal();
1131 <        return (interrupted || Thread.interrupted())? INTERRUPTED : 0L;
1131 >        return (interrupted || Thread.interrupted()) ? INTERRUPTED : 0L;
1132      }
1133  
1134      // Unsafe mechanics
# Line 1201 | Line 1202 | public class StampedLock implements java
1202      }
1203  
1204   }
1204

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines