2299 |
|
* @param check if <0, don't check resize, if <= 1 only check if uncontended |
2300 |
|
*/ |
2301 |
|
private final void addCount(long x, int check) { |
2302 |
< |
CounterCell[] as; long b, s; |
2303 |
< |
if ((as = counterCells) != null || |
2302 |
> |
CounterCell[] cs; long b, s; |
2303 |
> |
if ((cs = counterCells) != null || |
2304 |
|
!U.compareAndSetLong(this, BASECOUNT, b = baseCount, s = b + x)) { |
2305 |
< |
CounterCell a; long v; int m; |
2305 |
> |
CounterCell c; long v; int m; |
2306 |
|
boolean uncontended = true; |
2307 |
< |
if (as == null || (m = as.length - 1) < 0 || |
2308 |
< |
(a = as[ThreadLocalRandom.getProbe() & m]) == null || |
2307 |
> |
if (cs == null || (m = cs.length - 1) < 0 || |
2308 |
> |
(c = cs[ThreadLocalRandom.getProbe() & m]) == null || |
2309 |
|
!(uncontended = |
2310 |
< |
U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x))) { |
2310 |
> |
U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))) { |
2311 |
|
fullAddCount(x, uncontended); |
2312 |
|
return; |
2313 |
|
} |
2545 |
|
} |
2546 |
|
|
2547 |
|
final long sumCount() { |
2548 |
< |
CounterCell[] as = counterCells; |
2548 |
> |
CounterCell[] cs = counterCells; |
2549 |
|
long sum = baseCount; |
2550 |
< |
if (as != null) { |
2551 |
< |
for (CounterCell a : as) |
2552 |
< |
if (a != null) |
2553 |
< |
sum += a.value; |
2550 |
> |
if (cs != null) { |
2551 |
> |
for (CounterCell c : cs) |
2552 |
> |
if (c != null) |
2553 |
> |
sum += c.value; |
2554 |
|
} |
2555 |
|
return sum; |
2556 |
|
} |
2565 |
|
} |
2566 |
|
boolean collide = false; // True if last slot nonempty |
2567 |
|
for (;;) { |
2568 |
< |
CounterCell[] as; CounterCell a; int n; long v; |
2569 |
< |
if ((as = counterCells) != null && (n = as.length) > 0) { |
2570 |
< |
if ((a = as[(n - 1) & h]) == null) { |
2568 |
> |
CounterCell[] cs; CounterCell c; int n; long v; |
2569 |
> |
if ((cs = counterCells) != null && (n = cs.length) > 0) { |
2570 |
> |
if ((c = cs[(n - 1) & h]) == null) { |
2571 |
|
if (cellsBusy == 0) { // Try to attach new Cell |
2572 |
|
CounterCell r = new CounterCell(x); // Optimistic create |
2573 |
|
if (cellsBusy == 0 && |
2593 |
|
} |
2594 |
|
else if (!wasUncontended) // CAS already known to fail |
2595 |
|
wasUncontended = true; // Continue after rehash |
2596 |
< |
else if (U.compareAndSetLong(a, CELLVALUE, v = a.value, v + x)) |
2596 |
> |
else if (U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x)) |
2597 |
|
break; |
2598 |
< |
else if (counterCells != as || n >= NCPU) |
2598 |
> |
else if (counterCells != cs || n >= NCPU) |
2599 |
|
collide = false; // At max size or stale |
2600 |
|
else if (!collide) |
2601 |
|
collide = true; |
2602 |
|
else if (cellsBusy == 0 && |
2603 |
|
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) { |
2604 |
|
try { |
2605 |
< |
if (counterCells == as) // Expand table unless stale |
2606 |
< |
counterCells = Arrays.copyOf(as, n << 1); |
2605 |
> |
if (counterCells == cs) // Expand table unless stale |
2606 |
> |
counterCells = Arrays.copyOf(cs, n << 1); |
2607 |
|
} finally { |
2608 |
|
cellsBusy = 0; |
2609 |
|
} |
2612 |
|
} |
2613 |
|
h = ThreadLocalRandom.advanceProbe(h); |
2614 |
|
} |
2615 |
< |
else if (cellsBusy == 0 && counterCells == as && |
2615 |
> |
else if (cellsBusy == 0 && counterCells == cs && |
2616 |
|
U.compareAndSetInt(this, CELLSBUSY, 0, 1)) { |
2617 |
|
boolean init = false; |
2618 |
|
try { // Initialize table |
2619 |
< |
if (counterCells == as) { |
2619 |
> |
if (counterCells == cs) { |
2620 |
|
CounterCell[] rs = new CounterCell[2]; |
2621 |
|
rs[h & 1] = new CounterCell(x); |
2622 |
|
counterCells = rs; |