simpler std.event.Lock implementation
parent
058bfb254c
commit
de949b72c7
|
@ -106,35 +106,12 @@ pub const Lock = struct {
|
|||
// will attempt to grab the lock.
|
||||
_ = @atomicRmw(u8, &self.queue_empty_bit, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
|
||||
|
||||
while (true) {
|
||||
const old_bit = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
|
||||
if (old_bit != 0) {
|
||||
// We did not obtain the lock. Trust that our queue entry will resume us, and allow
|
||||
// suspend to complete.
|
||||
break;
|
||||
}
|
||||
// We got the lock. However we might have already been resumed from the queue.
|
||||
const old_bit = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
|
||||
if (old_bit == 0) {
|
||||
if (self.queue.get()) |node| {
|
||||
// Whether this node is us or someone else, we tail resume it.
|
||||
resume node.data;
|
||||
break;
|
||||
} else {
|
||||
// We already got resumed, and there are none left in the queue, which means that
|
||||
// we aren't even supposed to hold the lock right now.
|
||||
_ = @atomicRmw(u8, &self.queue_empty_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
|
||||
_ = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
|
||||
|
||||
// There might be a queue item. If we know the queue is empty, we can be done,
|
||||
// because the other actor will try to obtain the lock.
|
||||
// But if there's a queue item, we are the actor which must loop and attempt
|
||||
// to grab the lock again.
|
||||
if (@atomicLoad(u8, &self.queue_empty_bit, AtomicOrder.SeqCst) == 1) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue