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

Comparing jsr166/src/main/java/util/concurrent/ForkJoinWorkerThread.java (file contents):
Revision 1.5 by jsr166, Wed Jul 29 18:23:30 2009 UTC vs.
Revision 1.6 by jsr166, Fri Jul 31 20:41:13 2009 UTC

# Line 63 | Line 63 | public class ForkJoinWorkerThread extend
63       * which gives threads a chance to activate if necessary before
64       * stealing (see below).
65       *
66 +     * This approach also enables support for "async mode" where local
67 +     * task processing is in FIFO, not LIFO order; simply by using a
68 +     * version of deq rather than pop when locallyFifo is true (as set
69 +     * by the ForkJoinPool).  This allows use in message-passing
70 +     * frameworks in which tasks are never joined.
71 +     *
72       * Efficient implementation of this approach currently relies on
73       * an uncomfortable amount of "Unsafe" mechanics. To maintain
74       * correct orderings, reads and writes of variable base require
# Line 307 | Line 313 | public class ForkJoinWorkerThread extend
313       * one.  Marsaglia xor-shift is cheap and works well.
314       */
315      private static int xorShift(int r) {
316 <        r ^= r << 1;
317 <        r ^= r >>> 3;
318 <        r ^= r << 10;
313 <        return r;
316 >        r ^= (r << 13);
317 >        r ^= (r >>> 17);
318 >        return r ^ (r << 5);
319      }
320  
321      // Lifecycle methods
# Line 468 | Line 473 | public class ForkJoinWorkerThread extend
473      }
474  
475      /**
476 +     * Tries to take a task from the base of own queue, activating if
477 +     * necessary, failing only if empty. Called only by current thread.
478 +     *
479 +     * @return a task, or null if none
480 +     */
481 +    final ForkJoinTask<?> locallyDeqTask() {
482 +        int b;
483 +        while (sp != (b = base)) {
484 +            if (tryActivate()) {
485 +                ForkJoinTask<?>[] q = queue;
486 +                int i = (q.length - 1) & b;
487 +                ForkJoinTask<?> t = q[i];
488 +                if (t != null && casSlotNull(q, i, t)) {
489 +                    base = b + 1;
490 +                    return t;
491 +                }
492 +            }
493 +        }
494 +        return null;
495 +    }
496 +
497 +    /**
498       * Returns a popped task, or null if empty. Ensures active status
499       * if non-null. Called only by current thread.
500       */
# Line 507 | Line 534 | public class ForkJoinWorkerThread extend
534      }
535  
536      /**
537 <     * Returns next task.
537 >     * Returns next task or null if empty or contended
538       */
539      final ForkJoinTask<?> peekTask() {
540          ForkJoinTask<?>[] q = queue;
# Line 598 | Line 625 | public class ForkJoinWorkerThread extend
625       * @return a task, if available
626       */
627      final ForkJoinTask<?> pollTask() {
628 <        ForkJoinTask<?> t = locallyFifo ? deqTask() : popTask();
628 >        ForkJoinTask<?> t = locallyFifo ? locallyDeqTask() : popTask();
629          if (t == null && (t = scan()) != null)
630              ++stealCount;
631          return t;
# Line 610 | Line 637 | public class ForkJoinWorkerThread extend
637       * @return a task, if available
638       */
639      final ForkJoinTask<?> pollLocalTask() {
640 <        return locallyFifo ? deqTask() : popTask();
640 >        return locallyFifo ? locallyDeqTask() : popTask();
641      }
642  
643      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines