s += SEED_INCREMENT) || s == 0); // skip 0 WorkQueue w = new WorkQueue(this, wt, mode, s); if (((ps = plock) & PL_LOCK) != 0 || !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
final int externalHelpComplete(CountedCompleter<?> task) { WorkQueue joiner; int m, j; Submitter z = submitters.get(); WorkQueue[] ws = workQueues; int s = 0; if (z != null && ws != null && (m = ws.length - 1) >= 0 && (joiner = ws[(j = z.seed) & m & SQMASK]) != null && task != null) { int scans = m + m + 1; long c = 0L; // for stability check j |= 1; // poll odd queues for (int k = scans; ; j += 2) { WorkQueue q; if ((s = task.status) < 0) break; else if (joiner.externalPopAndExecCC(task)) k = scans; else if ((s = task.status) < 0) break; else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) k = scans; else if (--k < 0) { if (c == (c = ctl)) break; k = scans; } } } return s; }
try { // locked version of push if ((a != null && a.length > s + 1 - q.base) || (a = q.growArray()) != null) { // must presize int j = (((a.length - 1) & s) << ASHIFT) + ABASE; U.putOrderedObject(a, j, task); q = new WorkQueue(this, null, SHARED_QUEUE, r); q.poolIndex = (short)k; if (((ps = plock) & PL_LOCK) != 0 ||
w.cancelAll(); // cancel remaining tasks WorkQueue[] ws; WorkQueue v; Thread p; int u, i, e; while ((u = (int)((c = ctl) >>> 32)) < 0 && (e = (int)c) >= 0) {
for (int i = 0; i < ws.length; ++i) { if ((w = ws[i]) != null) { int size = w.queueSize(); if ((i & 1) == 0) qs += size; qt += size; st += w.nsteals; if (w.isApparentlyUnblocked()) ++rc;
for (boolean active = true;;) { long c; WorkQueue q; ForkJoinTask<?> t; int b; while ((t = w.nextLocalTask()) != null) t.doExec(); if ((q = findNonEmptyStealQueue()) != null) { ((c & AC_MASK) + AC_UNIT)))); if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) { (w.currentSteal = t).doExec(); w.currentSteal = ps;
for (int i = 0; i < ws.length; ++i) { if ((w = ws[i]) != null) { while ((t = w.poll()) != null) { c.add(t); ++count;
if ((s = task.status) < 0) break; else if (joiner.internalPopAndExecCC(task)) k = scans; else if ((s = task.status) < 0) break; else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) k = scans; else if (--k < 0) {
/** * Returns, but does not unschedule or execute, a task queued by * the current thread but not yet executed, if one is immediately * available. There is no guarantee that this task will actually * be polled or executed next. Conversely, this method may return * null even if a task exists but cannot be accessed without * contention with other threads. This method is designed * primarily to support extensions, and is unlikely to be useful * otherwise. * * @return the next task, or {@code null} if none are available */ protected static ForkJoinTask<?> peekNextLocalTask() { Thread t; ForkJoinPool.WorkQueue q; if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) q = ((ForkJoinWorkerThread)t).workQueue; else q = ForkJoinPool.commonSubmitterQueue(); return (q == null) ? null : q.peek(); }
/** * Returns an estimate of the number of worker threads that are * not blocked waiting to join tasks or for other managed * synchronization. This method may overestimate the * number of running threads. * * @return the number of worker threads */ public int getRunningThreadCount() { int rc = 0; WorkQueue[] ws; WorkQueue w; if ((ws = workQueues) != null) { for (int i = 1; i < ws.length; i += 2) { if ((w = ws[i]) != null && w.isApparentlyUnblocked()) ++rc; } } return rc; }
/** * Pushes a task. Call only by owner in unshared queues. (The * shared-queue version is embedded in method externalPush.) * * @param task the task. Caller must ensure non-null. * @throws RejectedExecutionException if array cannot be resized */ final void push(ForkJoinTask<?> task) { ForkJoinTask<?>[] a; ForkJoinPool p; int s = top, n; if ((a = array) != null) { // ignore if queue removed int m = a.length - 1; U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task); if ((n = (top = s + 1) - base) <= 2) (p = pool).signalWork(p.workQueues, this); else if (n >= m) growArray(); } }
/** * Removes and returns the next unexecuted submission if one is * available. This method may be useful in extensions to this * class that re-assign work in systems with multiple pools. * * @return the next submission, or {@code null} if none */ protected ForkJoinTask<?> pollSubmission() { WorkQueue[] ws; WorkQueue w; ForkJoinTask<?> t; if ((ws = workQueues) != null) { for (int i = 0; i < ws.length; i += 2) { if ((w = ws[i]) != null && (t = w.poll()) != null) return t; } } return null; }
/** * Returns {@code true} if there are any tasks submitted to this * pool that have not yet begun executing. * * @return {@code true} if there are any queued submissions */ public boolean hasQueuedSubmissions() { WorkQueue[] ws; WorkQueue w; if ((ws = workQueues) != null) { for (int i = 0; i < ws.length; i += 2) { if ((w = ws[i]) != null && !w.isEmpty()) return true; } } return false; }
/** * Gets and removes a local or stolen task for the given worker. * * @return a task, if available */ final ForkJoinTask<?> nextTaskFor(WorkQueue w) { for (ForkJoinTask<?> t;;) { WorkQueue q; int b; if ((t = w.nextLocalTask()) != null) return t; if ((q = findNonEmptyStealQueue()) == null) return null; if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) return t; } }
/** * Unschedules and returns, without executing, the next task * queued by the current thread but not yet executed, if the * current thread is operating in a ForkJoinPool. This method is * designed primarily to support extensions, and is unlikely to be * useful otherwise. * * @return the next task, or {@code null} if none are available */ protected static ForkJoinTask<?> pollNextLocalTask() { Thread t; return ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ? ((ForkJoinWorkerThread)t).workQueue.nextLocalTask() : null; }
/** * Top-level runloop for workers, called by ForkJoinWorkerThread.run. */ final void runWorker(WorkQueue w) { w.growArray(); // allocate queue for (int r = w.hint; scan(w, r) == 0; ) { r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift } }
/** * Polls and runs tasks until empty. */ final void pollAndExecAll() { for (ForkJoinTask<?> t; (t = poll()) != null;) t.doExec(); }
/** * Removes and cancels all known tasks, ignoring any exceptions. */ final void cancelAll() { ForkJoinTask.cancelIgnoringExceptions(currentJoin); ForkJoinTask.cancelIgnoringExceptions(currentSteal); for (ForkJoinTask<?> t; (t = poll()) != null; ) ForkJoinTask.cancelIgnoringExceptions(t); }