authorgravatar for 45520026+kprotty@users.noreply.github.comkprotty <45520026+kprotty@users.noreply.github.com> 2020-09-28 07:25:51-05:00
committergravatar for 45520026+kprotty@users.noreply.github.comkprotty <45520026+kprotty@users.noreply.github.com> 2020-09-28 07:25:51-05:00
log468a4bf0b443067b9d4a0bf68ea7e675a9bca727
treecd7c373e2e0077f237f158c96db166bc42a9cdc1
parenta31d9f92f282a878836a3ecac5a48d5f4037868c

address some review changes


1 files changed, 21 insertions(+), 4 deletions(-)

lib/std/event/lock.zig+21-4
......@@ -20,13 +20,14 @@ pub const Lock = struct {
2020 head: usize = UNLOCKED,
2121
2222 const UNLOCKED = 0;
23 const LOCKED = 69;
23 const LOCKED = 1;
2424
2525 const global_event_loop = Loop.instance orelse
2626 @compileError("std.event.Lock currently only works with event-based I/O");
2727
2828 const Waiter = struct {
29 next: ?*Waiter,
29 // forced Waiter alignment to ensure it doesn't clash with LOCKED
30 next: ?*Waiter align(2),
3031 tail: *Waiter,
3132 node: Loop.NextTickNode,
3233 };
......@@ -34,6 +35,14 @@ pub const Lock = struct {
3435 pub fn acquire(self: *Lock) Held {
3536 const held = self.mutex.acquire();
3637
38 // self.head transitions from multiple stages depending on the value:
39 // UNLOCKED -> LOCKED:
40 // acquire Lock ownership when theres no waiters
41 // LOCKED -> <Waiter head ptr>:
42 // Lock is already owned, enqueue first Waiter
43 // <head ptr> -> <head ptr>:
44 // Lock is owned with pending waiters. Push our waiter to the queue.
45
3746 if (self.head == UNLOCKED) {
3847 self.head = LOCKED;
3948 held.release();
......@@ -47,7 +56,7 @@ pub const Lock = struct {
4756 const head = switch (self.head) {
4857 UNLOCKED => unreachable,
4958 LOCKED => null,
50 else => @intToPtr(?*Waiter, self.head),
59 else => @intToPtr(*Waiter, self.head),
5160 };
5261
5362 if (head) |h| {
......@@ -77,9 +86,17 @@ pub const Lock = struct {
7786 const held = self.lock.mutex.acquire();
7887 defer held.release();
7988
89 // self.head goes through the reverse transition from acquire():
90 // <head ptr> -> <new head ptr>:
91 // pop a waiter from the queue to give Lock ownership when theres still others pending
92 // <head ptr> -> LOCKED:
93 // pop the laster waiter from the queue, while also giving it lock ownership when awaken
94 // LOCKED -> UNLOCKED:
95 // last lock owner releases lock while no one else is waiting for it
96
8097 switch (self.lock.head) {
8198 UNLOCKED => {
82 std.debug.panic("Lock unlocked when already unlocked", .{});
99 unreachable; // Lock unlocked while unlocking
83100 },
84101 LOCKED => {
85102 self.lock.head = UNLOCKED;