946 |
|
} |
947 |
|
|
948 |
|
/** |
949 |
– |
* Run tasks in local queue until given task is done. |
950 |
– |
* Not currently used because it complicates semantics. |
951 |
– |
* |
952 |
– |
* @param joinMe the task to join |
953 |
– |
*/ |
954 |
– |
private void localHelpJoinTask(ForkJoinTask<?> joinMe) { |
955 |
– |
int s; |
956 |
– |
ForkJoinTask<?>[] q; |
957 |
– |
while (joinMe.status >= 0 && (s = sp) != base && (q = queue) != null) { |
958 |
– |
int i = (q.length - 1) & --s; |
959 |
– |
long u = (i << qShift) + qBase; // raw offset |
960 |
– |
ForkJoinTask<?> t = q[i]; |
961 |
– |
if (t == null) // lost to a stealer |
962 |
– |
break; |
963 |
– |
if (UNSAFE.compareAndSwapObject(q, u, t, null)) { |
964 |
– |
/* |
965 |
– |
* This recheck (and similarly in helpJoinTask) |
966 |
– |
* handles cases where joinMe is independently |
967 |
– |
* cancelled or forced even though there is other work |
968 |
– |
* available. Back out of the pop by putting t back |
969 |
– |
* into slot before we commit by writing sp. |
970 |
– |
*/ |
971 |
– |
if (joinMe.status < 0) { |
972 |
– |
UNSAFE.putObjectVolatile(q, u, t); |
973 |
– |
break; |
974 |
– |
} |
975 |
– |
sp = s; |
976 |
– |
// UNSAFE.putOrderedInt(this, spOffset, s); |
977 |
– |
t.quietlyExec(); |
978 |
– |
} |
979 |
– |
} |
980 |
– |
} |
981 |
– |
|
982 |
– |
/** |
949 |
|
* Tries to locate and help perform tasks for a stealer of the |
950 |
|
* given task, or in turn one of its stealers. Traces |
951 |
|
* currentSteal->currentJoin links looking for a thread working on |
978 |
|
for (int j = 0; ; ++j) { // search array |
979 |
|
if (j < n) { |
980 |
|
ForkJoinTask<?> vs; |
981 |
< |
if ((v = ws[j]) != null && |
981 |
> |
if ((v = ws[j]) != null && v != this && |
982 |
|
(vs = v.currentSteal) != null) { |
983 |
|
if (joinMe.status < 0 || task.status < 0) |
984 |
|
return; // stale or done |