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

Comparing jsr166/src/jsr166y/ForkJoinTask.java (file contents):
Revision 1.49 by dl, Wed Jul 7 19:52:31 2010 UTC vs.
Revision 1.50 by dl, Fri Jul 23 13:07:43 2010 UTC

# Line 147 | Line 147 | public abstract class ForkJoinTask<V> im
147       * in a way that flows well in javadocs.
148       */
149  
150 <    /**
151 <     * Run control status bits packed into a single int to minimize
152 <     * footprint and to ensure atomicity (via CAS).  Status is
153 <     * initially zero, and takes on nonnegative values until
154 <     * completed, upon which status holds value COMPLETED. CANCELLED,
155 <     * or EXCEPTIONAL. Tasks undergoing blocking waits by other
156 <     * threads have the SIGNAL bit set.  Completion of a stolen task
157 <     * with SIGNAL set awakens any waiters via notifyAll. Even though
158 <     * suboptimal for some purposes, we use basic builtin wait/notify
159 <     * to take advantage of "monitor inflation" in JVMs that we would
160 <     * otherwise need to emulate to avoid adding further per-task
161 <     * bookkeeping overhead.  We want these monitors to be "fat",
162 <     * i.e., not use biasing or thin-lock techniques, so use some odd
163 <     * coding idioms that tend to avoid them.
150 >    /*
151 >     * The status field holds run control status bits packed into a
152 >     * single int to minimize footprint and to ensure atomicity (via
153 >     * CAS).  Status is initially zero, and takes on nonnegative
154 >     * values until completed, upon which status holds value
155 >     * COMPLETED. CANCELLED, or EXCEPTIONAL. Tasks undergoing blocking
156 >     * waits by other threads have the SIGNAL bit set.  Completion of
157 >     * a stolen task with SIGNAL set awakens any waiters via
158 >     * notifyAll. Even though suboptimal for some purposes, we use
159 >     * basic builtin wait/notify to take advantage of "monitor
160 >     * inflation" in JVMs that we would otherwise need to emulate to
161 >     * avoid adding further per-task bookkeeping overhead.  We want
162 >     * these monitors to be "fat", i.e., not use biasing or thin-lock
163 >     * techniques, so use some odd coding idioms that tend to avoid
164 >     * them.
165       */
166 +
167 +    /** Run status of this task */
168      volatile int status; // accessed directly by pool and workers
169  
170      private static final int NORMAL      = -1;
# Line 214 | Line 217 | public abstract class ForkJoinTask<V> im
217      /**
218       * Blocks a worker thread until completion. Called only by pool.
219       */
220 <    final int internalAwaitDone() {
221 <        int s;
220 >    final void internalAwaitDone() {
221 >        int s;         // the odd construction reduces lock bias effects
222          while ((s = status) >= 0) {
223 <            synchronized(this) {
224 <                if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)) {
225 <                    do {
226 <                        try {
224 <                            wait();
225 <                        } catch (InterruptedException ie) {
226 <                            cancelIfTerminating();
227 <                        }
228 <                    } while ((s = status) >= 0);
229 <                    break;
223 >            try {
224 >                synchronized(this) {
225 >                    if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
226 >                        wait();
227                  }
228 +            } catch (InterruptedException ie) {
229 +                cancelIfTerminating();
230              }
231          }
233        return s;
232      }
233  
234      /**
# Line 243 | Line 241 | public abstract class ForkJoinTask<V> im
241              synchronized(this) {
242                  if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
243                      boolean interrupted = false;
244 <                    do {
244 >                    while ((s = status) >= 0) {
245                          try {
246                              wait();
247                          } catch (InterruptedException ie) {
248                              interrupted = true;
249                          }
250 <                    } while ((s = status) >= 0);
250 >                    }
251                      if (interrupted)
252                          Thread.currentThread().interrupt();
253                      break;
# Line 297 | Line 295 | public abstract class ForkJoinTask<V> im
295                  if (completed)
296                      return setCompletion(NORMAL);
297              }
298 <            w.joinTask(this);
301 <            return status;
298 >            return w.joinTask(this);
299          }
300          return externalAwaitDone();
301      }
# Line 317 | Line 314 | public abstract class ForkJoinTask<V> im
314              } catch (Throwable rex) {
315                  return setExceptionalCompletion(rex);
316              }
317 <            if (completed)
321 <                stat = setCompletion(NORMAL);
322 <            else
323 <                stat = doJoin();
317 >            stat = completed ? setCompletion(NORMAL) : doJoin();
318          }
319          return stat;
320      }
# Line 538 | Line 532 | public abstract class ForkJoinTask<V> im
532       * @return {@code true} if this task is now cancelled
533       */
534      public boolean cancel(boolean mayInterruptIfRunning) {
535 <        setCompletion(CANCELLED);
542 <        return status == CANCELLED;
535 >        return setCompletion(CANCELLED) == CANCELLED;
536      }
537  
538      /**
# Line 556 | Line 549 | public abstract class ForkJoinTask<V> im
549      /**
550       * Cancels ignoring exceptions if worker is terminating
551       */
552 <    private void cancelIfTerminating() {
552 >    final void cancelIfTerminating() {
553          Thread t = Thread.currentThread();
554          if ((t instanceof ForkJoinWorkerThread) &&
555              ((ForkJoinWorkerThread) t).isTerminating()) {
# Line 1103 | Line 1096 | public abstract class ForkJoinTask<V> im
1096          Object ex = s.readObject();
1097          if (ex != null)
1098              setExceptionalCompletion((Throwable) ex);
1106        if (status < 0)
1107            synchronized (this) { notifyAll(); }
1099      }
1100  
1101      // Unsafe mechanics

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines