-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
std.mutex: implement blocking mutexes on Linux #1463
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
Conversation
41ab32c
to
8905f96
Compare
see ziglang#1455 Eventually I would like to see something like WTF::Lock/WTF::ParkingLot, but that is a bunch of work.
sto that the tests can pass
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.
This is an important component, so I am compelled to have high standards for acceptance. The logic here is nontrivial and difficult to reason about (because it deals with concurrency and atomic operations). So we need these things in order to accept it:
- Tests.
- Comments explaining in detail how the implementation works, so that one can verify the code matches the intended behavior.
- Documentation comments explaining the API, and what guarantees the user can or cannot get from it.
|
||
pub const Held = struct { | ||
mutex: *Mutex, | ||
|
||
pub fn release(self: Held) void { | ||
assert(@atomicRmw(u8, &self.mutex.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1); | ||
if (@atomicRmw(u32, &self.mutex.lock, AtomicRmwOp.Sub, 1, AtomicOrder.Release) != 1) { | ||
self.mutex.lock = 0; |
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.
You can't have a naked write racing with an atomic write (the cmpxchg on line 42).
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.
Why doesn't the @atomicRmw
do an xchg and set the value to 0? You can still check if the previous value was 1.
while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {} | ||
var c: u32 = undefined; | ||
// This need not be strong because of the loop that follows. | ||
// TODO implement mutex3 from https://www.akkadia.org/drepper/futex.pdf in x86 assembly. |
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.
Is that really better? Can we have an issue to discuss it rather than this TODO comment?
// spin-lock | ||
} | ||
} | ||
if (@cmpxchgWeak(u32, &self.lock, 0, 2, AtomicOrder.Acquire, AtomicOrder.Monotonic)) |value2| { |
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.
Why does this jump straight to the "locked with waiters" state? shouldn't it just go back and try the original cmpxchg again?
This is actually pretty well tested by the |
see #1455
Eventually I would like to see something like WTF::Lock/WTF::ParkingLot,
but that is a bunch of work.