ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/SynchronousQueue.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/SynchronousQueue.java (file contents):
Revision 1.68 by jsr166, Sun May 18 23:47:56 2008 UTC vs.
Revision 1.69 by dl, Sat Sep 4 14:57:32 2010 UTC

# Line 212 | Line 212 | public class SynchronousQueue<E> extends
212                  this.item = item;
213              }
214  
215            static final AtomicReferenceFieldUpdater<SNode, SNode>
216                nextUpdater = AtomicReferenceFieldUpdater.newUpdater
217                (SNode.class, SNode.class, "next");
218
215              boolean casNext(SNode cmp, SNode val) {
216 <                return (cmp == next &&
217 <                        nextUpdater.compareAndSet(this, cmp, val));
216 >                return cmp == next &&
217 >                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
218              }
219  
224            static final AtomicReferenceFieldUpdater<SNode, SNode>
225                matchUpdater = AtomicReferenceFieldUpdater.newUpdater
226                (SNode.class, SNode.class, "match");
227
220              /**
221               * Tries to match node s to this node, if so, waking up thread.
222               * Fulfillers call tryMatch to identify their waiters.
# Line 235 | Line 227 | public class SynchronousQueue<E> extends
227               */
228              boolean tryMatch(SNode s) {
229                  if (match == null &&
230 <                    matchUpdater.compareAndSet(this, null, s)) {
230 >                    UNSAFE.compareAndSwapObject(this, matchOffset, null, s)) {
231                      Thread w = waiter;
232                      if (w != null) {    // waiters need at most one unpark
233                          waiter = null;
# Line 250 | Line 242 | public class SynchronousQueue<E> extends
242               * Tries to cancel a wait by matching node to itself.
243               */
244              void tryCancel() {
245 <                matchUpdater.compareAndSet(this, null, this);
245 >                UNSAFE.compareAndSwapObject(this, matchOffset, null, this);
246              }
247  
248              boolean isCancelled() {
249                  return match == this;
250              }
251 +
252 +            // Unsafe mechanics
253 +            private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
254 +            private static final long nextOffset =
255 +                objectFieldOffset(UNSAFE, "next", SNode.class);
256 +            private static final long matchOffset =
257 +                objectFieldOffset(UNSAFE, "match", SNode.class);
258 +
259          }
260  
261          /** The head (top) of the stack */
262          volatile SNode head;
263 <
264 <        static final AtomicReferenceFieldUpdater<TransferStack, SNode>
265 <            headUpdater = AtomicReferenceFieldUpdater.newUpdater
266 <            (TransferStack.class,  SNode.class, "head");
267 <
263 >        
264          boolean casHead(SNode h, SNode nh) {
265 <            return h == head && headUpdater.compareAndSet(this, h, nh);
265 >            return h == head &&
266 >                UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
267          }
268  
269          /**
# Line 470 | Line 467 | public class SynchronousQueue<E> extends
467                      p = n;
468              }
469          }
470 +
471 +        // Unsafe mechanics
472 +        private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
473 +        private static final long headOffset =
474 +            objectFieldOffset(UNSAFE, "head", TransferStack.class);
475 +
476      }
477  
478      /** Dual Queue */
# Line 495 | Line 498 | public class SynchronousQueue<E> extends
498                  this.isData = isData;
499              }
500  
498            static final AtomicReferenceFieldUpdater<QNode, QNode>
499                nextUpdater = AtomicReferenceFieldUpdater.newUpdater
500                (QNode.class, QNode.class, "next");
501
501              boolean casNext(QNode cmp, QNode val) {
502 <                return (next == cmp &&
503 <                        nextUpdater.compareAndSet(this, cmp, val));
502 >                return next == cmp &&
503 >                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
504              }
505  
507            static final AtomicReferenceFieldUpdater<QNode, Object>
508                itemUpdater = AtomicReferenceFieldUpdater.newUpdater
509                (QNode.class, Object.class, "item");
510
506              boolean casItem(Object cmp, Object val) {
507 <                return (item == cmp &&
508 <                        itemUpdater.compareAndSet(this, cmp, val));
507 >                return item == cmp &&
508 >                    UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
509              }
510  
511              /**
512               * Tries to cancel by CAS'ing ref to this as item.
513               */
514              void tryCancel(Object cmp) {
515 <                itemUpdater.compareAndSet(this, cmp, this);
515 >                UNSAFE.compareAndSwapObject(this, itemOffset, cmp, this);
516              }
517 <
517 >            
518              boolean isCancelled() {
519                  return item == this;
520              }
# Line 532 | Line 527 | public class SynchronousQueue<E> extends
527              boolean isOffList() {
528                  return next == this;
529              }
530 +
531 +            // Unsafe mechanics
532 +            private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
533 +            private static final long nextOffset =
534 +                objectFieldOffset(UNSAFE, "next", QNode.class);
535 +            private static final long itemOffset =
536 +                objectFieldOffset(UNSAFE, "item", QNode.class);
537          }
538  
539          /** Head of queue */
# Line 551 | Line 553 | public class SynchronousQueue<E> extends
553              tail = h;
554          }
555  
554        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
555            headUpdater = AtomicReferenceFieldUpdater.newUpdater
556            (TransferQueue.class,  QNode.class, "head");
557
556          /**
557           * Tries to cas nh as new head; if successful, unlink
558           * old head's next node to avoid garbage retention.
559           */
560          void advanceHead(QNode h, QNode nh) {
561 <            if (h == head && headUpdater.compareAndSet(this, h, nh))
561 >            if (h == head &&
562 >                UNSAFE.compareAndSwapObject(this, headOffset, h, nh))
563                  h.next = h; // forget old next
564          }
565  
567        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
568            tailUpdater = AtomicReferenceFieldUpdater.newUpdater
569            (TransferQueue.class, QNode.class, "tail");
570
566          /**
567           * Tries to cas nt as new tail.
568           */
569          void advanceTail(QNode t, QNode nt) {
570              if (tail == t)
571 <                tailUpdater.compareAndSet(this, t, nt);
571 >                UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);
572          }
573  
579        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
580            cleanMeUpdater = AtomicReferenceFieldUpdater.newUpdater
581            (TransferQueue.class, QNode.class, "cleanMe");
582
574          /**
575           * Tries to CAS cleanMe slot.
576           */
577          boolean casCleanMe(QNode cmp, QNode val) {
578 <            return (cleanMe == cmp &&
579 <                    cleanMeUpdater.compareAndSet(this, cmp, val));
578 >            return cleanMe == cmp &&
579 >                UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
580          }
581  
582          /**
# Line 770 | Line 761 | public class SynchronousQueue<E> extends
761                      return;          // Postpone cleaning s
762              }
763          }
764 +
765 +        // unsafe mechanics
766 +        private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
767 +        private static final long headOffset =
768 +            objectFieldOffset(UNSAFE, "head", TransferQueue.class);
769 +        private static final long tailOffset =
770 +            objectFieldOffset(UNSAFE, "tail", TransferQueue.class);
771 +        private static final long cleanMeOffset =
772 +            objectFieldOffset(UNSAFE, "cleanMe", TransferQueue.class);
773 +        
774      }
775  
776      /**
# Line 1112 | Line 1113 | public class SynchronousQueue<E> extends
1113              transferer = new TransferStack();
1114      }
1115  
1116 +    // Unsafe mechanics
1117 +    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
1118 +                                  String field, Class<?> klazz) {
1119 +        try {
1120 +            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
1121 +        } catch (NoSuchFieldException e) {
1122 +            // Convert Exception to corresponding Error
1123 +            NoSuchFieldError error = new NoSuchFieldError(field);
1124 +            error.initCause(e);
1125 +            throw error;
1126 +        }
1127 +    }
1128 +
1129   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines