authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-31 19:57:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-31 19:57:46-04:00
logde949b72c791477c29155ee09a1c5c3d4ab56033
tree9c7f3e6e532c3450ddb726dda960c1193b21c26e
parent058bfb254c4c0e1cfb254791f771c88c74f299e8

simpler std.event.Lock implementation


1 files changed, 2 insertions(+), 25 deletions(-)

std/event/lock.zig+2-25
......@@ -106,35 +106,12 @@ pub const Lock = struct {
106106 // will attempt to grab the lock.
107107 _ = @atomicRmw(u8, &self.queue_empty_bit, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
108108
109 while (true) {
110 const old_bit = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
111 if (old_bit != 0) {
112 // We did not obtain the lock. Trust that our queue entry will resume us, and allow
113 // suspend to complete.
114 break;
115 }
116 // We got the lock. However we might have already been resumed from the queue.
109 const old_bit = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
110 if (old_bit == 0) {
117111 if (self.queue.get()) |node| {
118112 // Whether this node is us or someone else, we tail resume it.
119113 resume node.data;
120 break;
121 } else {
122 // We already got resumed, and there are none left in the queue, which means that
123 // we aren't even supposed to hold the lock right now.
124 _ = @atomicRmw(u8, &self.queue_empty_bit, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
125 _ = @atomicRmw(u8, &self.shared_bit, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
126
127 // There might be a queue item. If we know the queue is empty, we can be done,
128 // because the other actor will try to obtain the lock.
129 // But if there's a queue item, we are the actor which must loop and attempt
130 // to grab the lock again.
131 if (@atomicLoad(u8, &self.queue_empty_bit, AtomicOrder.SeqCst) == 1) {
132 break;
133 } else {
134 continue;
135 }
136114 }
137 unreachable;
138115 }
139116 }
140117