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
Fix Ordering on WordLock (tsan detected) #292
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -154,7 +154,7 @@ impl WordLock { | |
if let Err(x) = self.state.compare_exchange_weak( | ||
state, | ||
state.with_queue_head(thread_data), | ||
Ordering::Release, | ||
Ordering::AcqRel, | ||
Ordering::Relaxed, | ||
) { | ||
return x; | ||
|
@@ -189,7 +189,7 @@ impl WordLock { | |
match self.state.compare_exchange_weak( | ||
state, | ||
state | QUEUE_LOCKED_BIT, | ||
Ordering::Acquire, | ||
Ordering::AcqRel, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This (and the changes below) doesn't make sense: there's nothing to release. The lock itself was already released in However I am noticing that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, my bad, yeah I see, I didn't look that closely, and thought this was still trying to unlock not to wake up threads 😅
So, this doesn't make sense to me, since it enters a loop that can only be exited by either returning (in which case the data in behind the ptr inside state is not read) or by passing the cmpxchg, which gives the Acquire. ... And in fact, yeah, I was mistaken that this needed AcqRel — this one was actually fine as Acquire. (Sorry...) Actually, I think Regardless, if I apply the normal workaround for acquire fences under TSan (where you replace a fence with a discarded acquire load), then L252/L233 can both use Release. (Just to make extra-sure, I verified that the change on L157 is needed with or without the tsan fence fix). I'll have an updated patch shortly. |
||
Ordering::Relaxed, | ||
) { | ||
Ok(_) => break, | ||
|
@@ -230,7 +230,7 @@ impl WordLock { | |
match self.state.compare_exchange_weak( | ||
state, | ||
state & !QUEUE_LOCKED_BIT, | ||
Ordering::Release, | ||
Ordering::AcqRel, | ||
Ordering::Relaxed, | ||
) { | ||
Ok(_) => return, | ||
|
@@ -249,7 +249,7 @@ impl WordLock { | |
match self.state.compare_exchange_weak( | ||
state, | ||
state & LOCKED_BIT, | ||
Ordering::Release, | ||
Ordering::AcqRel, | ||
Ordering::Relaxed, | ||
) { | ||
Ok(_) => break, | ||
|
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.
Nice catch! Thinking about it for a bit, an acquire is indeed needed here so that the call to
park
happens after the thread is inserted into the queue.