1660 |
|
} |
1661 |
|
} |
1662 |
|
|
1663 |
– |
/** |
1664 |
– |
* Helps and/or blocks until the given task is done or timeout. |
1665 |
– |
* First tries locally helping, then scans other queues for a task |
1666 |
– |
* produced by one of w's stealers; compensating and blocking if |
1667 |
– |
* none are found (rescanning if tryCompensate fails). |
1668 |
– |
* |
1669 |
– |
* @param w caller |
1670 |
– |
* @param task the task |
1671 |
– |
* @param deadline for timed waits, if nonzero |
1672 |
– |
* @return task status on exit |
1673 |
– |
*/ |
1674 |
– |
final int xawaitJoin(WorkQueue w, ForkJoinTask<?> task, long deadline) { |
1675 |
– |
int s = 0; |
1676 |
– |
if (w != null && task != null && |
1677 |
– |
(!(task instanceof CountedCompleter) || |
1678 |
– |
(s = w.localHelpCC((CountedCompleter<?>)task, 0)) >= 0)) { |
1679 |
– |
w.tryRemoveAndExec(task); |
1680 |
– |
int src = w.source, id = w.id, block = 0; |
1681 |
– |
s = task.status; |
1682 |
– |
while (s >= 0) { |
1683 |
– |
WorkQueue[] ws; |
1684 |
– |
boolean nonempty = false; |
1685 |
– |
int r = ThreadLocalRandom.nextSecondarySeed() | 1; // odd indices |
1686 |
– |
if ((ws = workQueues) != null) { // scan for matching id |
1687 |
– |
for (int n = ws.length, j = n, m = n - 1; j > 0; --j) { |
1688 |
– |
WorkQueue q; int i, b, al; ForkJoinTask<?>[] a; |
1689 |
– |
if ((i = r & m) >= 0 && i < n && |
1690 |
– |
(q = ws[i]) != null && q.source == id && |
1691 |
– |
(b = q.base) - q.top < 0 && |
1692 |
– |
(a = q.array) != null && (al = a.length) > 0) { |
1693 |
– |
int qid = q.id; |
1694 |
– |
if (block > 0) |
1695 |
– |
U.getAndAddLong(this, CTL, RC_UNIT); |
1696 |
– |
block = 0; |
1697 |
– |
int index = (al - 1) & b; |
1698 |
– |
long offset = ((long)index << ASHIFT) + ABASE; |
1699 |
– |
ForkJoinTask<?> t = (ForkJoinTask<?>) |
1700 |
– |
U.getObjectVolatile(a, offset); |
1701 |
– |
if (t != null && b++ == q.base && id == q.source && |
1702 |
– |
U.compareAndSwapObject(a, offset, t, null)) { |
1703 |
– |
q.base = b; |
1704 |
– |
w.source = qid; |
1705 |
– |
t.doExec(); |
1706 |
– |
w.source = src; |
1707 |
– |
} |
1708 |
– |
nonempty = true; |
1709 |
– |
break; |
1710 |
– |
} |
1711 |
– |
else |
1712 |
– |
r += 2; |
1713 |
– |
} |
1714 |
– |
} |
1715 |
– |
if ((s = task.status) < 0) |
1716 |
– |
break; |
1717 |
– |
else if (!nonempty) { |
1718 |
– |
long ms, ns; |
1719 |
– |
if (deadline == 0L) |
1720 |
– |
ms = 0L; // untimed |
1721 |
– |
else if ((ns = deadline - System.nanoTime()) <= 0L) |
1722 |
– |
break; // timeout |
1723 |
– |
else if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) <= 0L) |
1724 |
– |
ms = 1L; // avoid 0 for timed wait |
1725 |
– |
if (block == 0) |
1726 |
– |
block = tryCompensate(w); |
1727 |
– |
else |
1728 |
– |
task.internalWait(ms); |
1729 |
– |
s = task.status; |
1730 |
– |
} |
1731 |
– |
} |
1732 |
– |
if (block > 0) |
1733 |
– |
U.getAndAddLong(this, CTL, RC_UNIT); |
1734 |
– |
} |
1735 |
– |
return s; |
1736 |
– |
} |
1737 |
– |
|
1663 |
|
final int awaitJoin(WorkQueue w, ForkJoinTask<?> task, long deadline) { |
1664 |
|
int s = 0; |
1665 |
|
if (w != null && task != null && |