344 |
|
* When these cases arise, rather than always retraversing the |
345 |
|
* entire list to find an actual predecessor to unlink (which |
346 |
|
* won't help for case (1) anyway), we record a conservative |
347 |
< |
* estimate of possible unsplice failures (in "sweepVotes"). We |
348 |
< |
* trigger a full sweep when the estimate exceeds a threshold |
349 |
< |
* indicating the maximum number of estimated removal failures to |
350 |
< |
* tolerate before sweeping through, unlinking cancelled nodes |
351 |
< |
* that were not unlinked upon initial removal. We perform sweeps |
352 |
< |
* by the thread hitting threshold (rather than background threads |
353 |
< |
* or by spreading work to other threads) because in the main |
354 |
< |
* contexts in which removal occurs, the caller is already |
355 |
< |
* timed-out, cancelled, or performing a potentially O(n) |
356 |
< |
* operation (i.e., remove(x)), none of which are time-critical |
357 |
< |
* enough to warrant the overhead that alternatives would impose |
358 |
< |
* on other threads. |
347 |
> |
* estimate of possible unsplice failures (in "sweepVotes"). |
348 |
> |
* We trigger a full sweep when the estimate exceeds a threshold |
349 |
> |
* ("SWEEP_THRESHOLD") indicating the maximum number of estimated |
350 |
> |
* removal failures to tolerate before sweeping through, unlinking |
351 |
> |
* cancelled nodes that were not unlinked upon initial removal. |
352 |
> |
* We perform sweeps by the thread hitting threshold (rather than |
353 |
> |
* background threads or by spreading work to other threads) |
354 |
> |
* because in the main contexts in which removal occurs, the |
355 |
> |
* caller is already timed-out, cancelled, or performing a |
356 |
> |
* potentially O(n) operation (e.g. remove(x)), none of which are |
357 |
> |
* time-critical enough to warrant the overhead that alternatives |
358 |
> |
* would impose on other threads. |
359 |
|
* |
360 |
|
* Because the sweepVotes estimate is conservative, and because |
361 |
|
* nodes become unlinked "naturally" as they fall off the head of |
428 |
|
} |
429 |
|
|
430 |
|
/** |
431 |
< |
* Creates a new node. Uses relaxed write because item can only |
432 |
< |
* be seen if followed by CAS. |
431 |
> |
* Constructs a new node. Uses relaxed write because item can |
432 |
> |
* only be seen after publication via casNext. |
433 |
|
*/ |
434 |
|
Node(Object item, boolean isData) { |
435 |
|
UNSAFE.putObject(this, itemOffset, item); // relaxed write |
877 |
|
} |
878 |
|
|
879 |
|
/** |
880 |
< |
* Unlinks matched nodes encountered in a traversal from head. |
880 |
> |
* Unlinks matched (typically cancelled) nodes encountered in a |
881 |
> |
* traversal from head. |
882 |
|
*/ |
883 |
|
private void sweep() { |
884 |
|
for (Node p = head, s, n; p != null && (s = p.next) != null; ) { |
885 |
< |
if (p == s) // stale |
886 |
< |
p = head; |
886 |
< |
else if (!s.isMatched()) |
885 |
> |
if (!s.isMatched()) |
886 |
> |
// Unmatched nodes are never self-linked |
887 |
|
p = s; |
888 |
|
else if ((n = s.next) == null) // trailing node is pinned |
889 |
|
break; |
890 |
+ |
else if (s == n) // stale |
891 |
+ |
// No need to also check for p == s, since that implies s == n |
892 |
+ |
p = head; |
893 |
|
else |
894 |
|
p.casNext(s, n); |
895 |
|
} |