282 |
|
|
283 |
|
private static int unarrivedOf(long s) { |
284 |
|
int counts = (int)s; |
285 |
< |
return (counts == EMPTY) ? 0 : counts & UNARRIVED_MASK; |
285 |
> |
return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); |
286 |
|
} |
287 |
|
|
288 |
|
private static int partiesOf(long s) { |
351 |
|
for (;;) { |
352 |
|
long s = (root == this) ? state : reconcileState(); |
353 |
|
int phase = (int)(s >>> PHASE_SHIFT); |
354 |
– |
int counts = (int)s; |
355 |
– |
int unarrived = (counts & UNARRIVED_MASK) - 1; |
354 |
|
if (phase < 0) |
355 |
|
return phase; |
356 |
< |
else if (counts == EMPTY || unarrived < 0) { |
357 |
< |
if (root == this || reconcileState() == s) |
358 |
< |
throw new IllegalStateException(badArrive(s)); |
359 |
< |
} |
360 |
< |
else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) { |
356 |
> |
int counts = (int)s; |
357 |
> |
int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); |
358 |
> |
if (unarrived <= 0) |
359 |
> |
throw new IllegalStateException(badArrive(s)); |
360 |
> |
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) { |
361 |
|
long n = s & PARTIES_MASK; // base of next state |
362 |
|
int nextUnarrived = (int)n >>> PARTIES_SHIFT; |
363 |
< |
if (unarrived == 0) { |
363 |
> |
if (unarrived == 1) { |
364 |
|
if (root == this) { |
365 |
|
if (onAdvance(phase, nextUnarrived)) |
366 |
|
n |= TERMINATION_BIT; |
368 |
|
n |= EMPTY; |
369 |
|
else |
370 |
|
n |= nextUnarrived; |
371 |
< |
n |= (long)((phase + 1) & MAX_PHASE) << PHASE_SHIFT; |
371 |
> |
int nextPhase = (phase + 1) & MAX_PHASE; |
372 |
> |
n |= (long)nextPhase << PHASE_SHIFT; |
373 |
|
UNSAFE.compareAndSwapLong(this, stateOffset, s, n); |
374 |
|
} |
375 |
|
else if (nextUnarrived == 0) { // propagate deregistration |
644 |
|
for (;;) { |
645 |
|
long s = (root == this) ? state : reconcileState(); |
646 |
|
int phase = (int)(s >>> PHASE_SHIFT); |
648 |
– |
int counts = (int)s; |
649 |
– |
int unarrived = (counts & UNARRIVED_MASK) - 1; |
647 |
|
if (phase < 0) |
648 |
|
return phase; |
649 |
< |
else if (counts == EMPTY || unarrived < 0) { |
650 |
< |
if (reconcileState() == s) |
651 |
< |
throw new IllegalStateException(badArrive(s)); |
652 |
< |
} |
653 |
< |
else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, |
654 |
< |
s -= ONE_ARRIVAL)) { |
655 |
< |
if (unarrived != 0) |
649 |
> |
int counts = (int)s; |
650 |
> |
int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); |
651 |
> |
if (unarrived <= 0) |
652 |
> |
throw new IllegalStateException(badArrive(s)); |
653 |
> |
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, |
654 |
> |
s -= ONE_ARRIVAL)) { |
655 |
> |
if (unarrived > 1) |
656 |
|
return root.internalAwaitAdvance(phase, null); |
657 |
|
if (root != this) |
658 |
|
return parent.arriveAndAwaitAdvance(); |
992 |
|
|
993 |
|
/** |
994 |
|
* Possibly blocks and waits for phase to advance unless aborted. |
995 |
< |
* Call only from root node. |
995 |
> |
* Call only on root phaser. |
996 |
|
* |
997 |
|
* @param phase current phase |
998 |
|
* @param node if non-null, the wait node to track interrupt and timeout; |
1000 |
|
* @return current phase |
1001 |
|
*/ |
1002 |
|
private int internalAwaitAdvance(int phase, QNode node) { |
1003 |
+ |
// assert root == this; |
1004 |
|
releaseWaiters(phase-1); // ensure old queue clean |
1005 |
|
boolean queued = false; // true when node is enqueued |
1006 |
|
int lastUnarrived = 0; // to increase spins upon change |