-
Notifications
You must be signed in to change notification settings - Fork 478
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
Return Some
for only one thread when calling remove()
#1143
Conversation
Thanks! Is it possible to add a test for the cases this would fix? |
I've added a test. Unfortunately, since this is a race condition, it is highly architecture-dependent and flaky: it should never spuriously fail, but it might spuriously succeed (ie. fail to detect a regression). On my machine (aarch64, Apple M1 Pro), without the changes in this PR, a typical result is:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks again!
I've observed that
SkipSet::remove()
sometimes appears to behave non-atomically: when multiple threads concurrently remove the same key, sometimes multiple threads get a return value of Some.The issue appears to be inside
SkipList::remove()
, as the call toself.search_position()
races with the call ton.mark_tower()
: if another thread marksn
immediately before the call ton.mark_tower()
, both threads will still return Some. This PR ensures that remove() returns None if the node was already marked.I can confirm that I've been unable to reproduce the issue after applying this PR.