Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simpler and faster lock-free linked list #1565

Merged
merged 1 commit into from
Mar 4, 2020
Merged

Simpler and faster lock-free linked list #1565

merged 1 commit into from
Mar 4, 2020

Conversation

elizarov
Copy link
Contributor

@elizarov elizarov commented Sep 23, 2019

Lock-free list implementation is considerably simplified, taking into
account a limited number of operations that it needs to support.

  • prev pointers in the list are not marked for removal, since we
    don't need to support linearizable backwards iteration.
  • helpDelete method is completely removed. All "delete-helping" is
    performed only by correctPrev method.
  • correctPrev method bails out when the node it works on is removed to
    reduce contention during concurrent removals.
  • Special open methods "isRemoved" and "nextIfRemoved" are introduced
    and are overriden in list head class (which is never removed).
    This ensures that on long list "removeFist" operation (touching head)
    does not interfere with "addLast" (touch tail). There is still
    sharing of cache-lines in this case, but no helping between them.

All in all, this improvement reduces the size of implementation code
and makes it considerably faster. Operations on LinkedListChannel are
now much faster (see timings of ChannelSendReceiveStressTest).

@elizarov elizarov requested a review from qwwdfsad September 23, 2019 10:18
@elizarov
Copy link
Contributor Author

elizarov commented Sep 23, 2019

DO NOT MERGE. Fails on stress test: https://teamcity.jetbrains.com/viewLog.html?buildId=2544675&buildTypeId=KotlinTools_KotlinxCoroutines_NightlyStressWindows False alarm. That is the old code. This bug was fixed.

@elizarov
Copy link
Contributor Author

elizarov commented Sep 24, 2019

ConflatedChannel starvation is too pronounced with this version. Need to do something about it. See https://teamcity.jetbrains.com/viewLog.html?buildId=2546814&buildTypeId=KotlinTools_KotlinxCoroutines_NightlyStressWindows Solved!

@elizarov elizarov force-pushed the faster-list branch 3 times, most recently from d381216 to 5f6d127 Compare October 3, 2019 11:19
@elizarov
Copy link
Contributor Author

elizarov commented Oct 3, 2019

Not ready for review yet. There is a potential problem with broken lists structure that should be investigate (still validate does not pass after LockFreeLinkedListLongStressTest.

@elizarov elizarov force-pushed the faster-list branch 2 times, most recently from 5a6a7d9 to 94b644f Compare October 19, 2019 16:30
@elizarov elizarov changed the title Simpler and faster lock-free linked list [DRAFT] Simpler and faster lock-free linked list Nov 28, 2019
@elizarov elizarov changed the title [DRAFT] Simpler and faster lock-free linked list Simpler and faster lock-free linked list Feb 13, 2020
@elizarov
Copy link
Contributor Author

It is ready for review now. Due to the previously merged improvements to ConflatedChannel this change is now straightforward and reliably passes all tests, tested on stress-tests, too.

Lock-free list implementation is considerably simplified, taking into
account a limited number of operations that it needs to support.

* prev pointers in the list are not marked for removal, since we
  don't need to support linearizable backwards iteration.
* helpDelete method is completely removed. All "delete-helping" is
  performed only by correctPrev method.
* correctPrev method bails out when the node it works on is removed to
  reduce contention during concurrent removals.
* Special open methods "isRemoved" and "nextIfRemoved" are introduced
  and are overridden in list head class (which is never removed).
  This ensures that on long list "removeFist" operation (touching head)
  does not interfere with "addLast" (touch tail). There is still
  sharing of cache-lines in this case, but no helping between them.

All in all, this improvement reduces the size of implementation code
and makes it considerably faster. Operations on LinkedListChannel are
now much faster (see timings of ChannelSendReceiveStressTest).
@elizarov elizarov merged commit 6862afc into develop Mar 4, 2020
@elizarov elizarov deleted the faster-list branch March 4, 2020 13:17
elizarov added a commit that referenced this pull request Mar 5, 2020
* The problem was introduced by #1565. When doing concurrent add+removeFirst the following can happen:
  - "add" completes, but has not correct prev pointer in next node yet
  - "removeFirst" removes freshly added element
  - "add" performs "finishAdd" that adjust prev pointer of the next node and thus removed element is pointed from the list again
* A separate LockFreeLinkedListAddRemoveStressTest is added that reproduces this problem.
* The old LockFreeLinkedListAtomicLFStressTest is refactored a bit.
qwwdfsad pushed a commit that referenced this pull request Mar 6, 2020
…st (#1845)

* The problem was introduced by #1565. When doing concurrent add+removeFirst the following can happen:
  - "add" completes, but has not correct prev pointer in next node yet
  - "removeFirst" removes freshly added element
  - "add" performs "finishAdd" that adjust prev pointer of the next node and thus removed element is pointed from the list again
* A separate LockFreeLinkedListAddRemoveStressTest is added that reproduces this problem.
* The old LockFreeLinkedListAtomicLFStressTest is refactored a bit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants