276 |
|
// some special values |
277 |
|
private static final int ONE_ARRIVAL = 1; |
278 |
|
private static final int ONE_PARTY = 1 << PARTIES_SHIFT; |
279 |
+ |
private static final int ONE_DEREGISTER = ONE_ARRIVAL|ONE_PARTY; |
280 |
|
private static final int EMPTY = 1; |
281 |
|
|
282 |
|
// The following unpacking methods are usually manually inlined |
344 |
|
* Manually tuned to speed up and minimize race windows for the |
345 |
|
* common case of just decrementing unarrived field. |
346 |
|
* |
347 |
< |
* @param deregister false for arrive, true for arriveAndDeregister |
347 |
> |
* @param adjust value to subtract from state; |
348 |
> |
* ONE_ARRIVAL for arrive, |
349 |
> |
* ONE_DEREGISTER for arriveAndDeregister |
350 |
|
*/ |
351 |
< |
private int doArrive(boolean deregister) { |
349 |
< |
int adj = deregister ? ONE_ARRIVAL|ONE_PARTY : ONE_ARRIVAL; |
351 |
> |
private int doArrive(int adjust) { |
352 |
|
final Phaser root = this.root; |
353 |
|
for (;;) { |
354 |
|
long s = (root == this) ? state : reconcileState(); |
359 |
|
int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); |
360 |
|
if (unarrived <= 0) |
361 |
|
throw new IllegalStateException(badArrive(s)); |
362 |
< |
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) { |
362 |
> |
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) { |
363 |
|
if (unarrived == 1) { |
364 |
|
long n = s & PARTIES_MASK; // base of next state |
365 |
|
int nextUnarrived = (int)n >>> PARTIES_SHIFT; |
375 |
|
UNSAFE.compareAndSwapLong(this, stateOffset, s, n); |
376 |
|
} |
377 |
|
else if (nextUnarrived == 0) { // propagate deregistration |
378 |
< |
phase = parent.doArrive(true); |
378 |
> |
phase = parent.doArrive(ONE_DEREGISTER); |
379 |
|
UNSAFE.compareAndSwapLong(this, stateOffset, |
380 |
|
s, s | EMPTY); |
381 |
|
} |
382 |
|
else |
383 |
< |
phase = parent.doArrive(false); |
383 |
> |
phase = parent.doArrive(ONE_ARRIVAL); |
384 |
|
releaseWaiters(phase); |
385 |
|
} |
386 |
|
return phase; |
396 |
|
*/ |
397 |
|
private int doRegister(int registrations) { |
398 |
|
// adjustment to state |
399 |
< |
long adj = ((long)registrations << PARTIES_SHIFT) | registrations; |
399 |
> |
long adjust = ((long)registrations << PARTIES_SHIFT) | registrations; |
400 |
|
final Phaser parent = this.parent; |
401 |
|
int phase; |
402 |
|
for (;;) { |
413 |
|
if (unarrived == 0) // wait out advance |
414 |
|
root.internalAwaitAdvance(phase, null); |
415 |
|
else if (UNSAFE.compareAndSwapLong(this, stateOffset, |
416 |
< |
s, s + adj)) |
416 |
> |
s, s + adjust)) |
417 |
|
break; |
418 |
|
} |
419 |
|
} |
420 |
|
else if (parent == null) { // 1st root registration |
421 |
< |
long next = ((long)phase << PHASE_SHIFT) | adj; |
421 |
> |
long next = ((long)phase << PHASE_SHIFT) | adjust; |
422 |
|
if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next)) |
423 |
|
break; |
424 |
|
} |
431 |
|
// assert phase < 0 || (int)state == EMPTY; |
432 |
|
} while (!UNSAFE.compareAndSwapLong |
433 |
|
(this, stateOffset, state, |
434 |
< |
((long)phase << PHASE_SHIFT) | adj)); |
434 |
> |
((long)phase << PHASE_SHIFT) | adjust)); |
435 |
|
break; |
436 |
|
} |
437 |
|
} |
599 |
|
* of unarrived parties would become negative |
600 |
|
*/ |
601 |
|
public int arrive() { |
602 |
< |
return doArrive(false); |
602 |
> |
return doArrive(ONE_ARRIVAL); |
603 |
|
} |
604 |
|
|
605 |
|
/** |
619 |
|
* of registered or unarrived parties would become negative |
620 |
|
*/ |
621 |
|
public int arriveAndDeregister() { |
622 |
< |
return doArrive(true); |
622 |
> |
return doArrive(ONE_DEREGISTER); |
623 |
|
} |
624 |
|
|
625 |
|
/** |