authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-18 16:14:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-20 15:08:59-07:00
log32fd637e57c3b4391b3f2f4499c803e3d4e8f615
treeaae454bf4df2d46f83b6614304dbc1ec92ef3bd5
parent0d1cd0d4822628c104890af4c31cdf38c6f96d35

stage2: replace WaitGroup with a trivially auditable one


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

src/WaitGroup.zig+21-9
...@@ -1,22 +1,34 @@...@@ -1,22 +1,34 @@
1const std = @import("std");1const std = @import("std");
2const WaitGroup = @This();2const WaitGroup = @This();
33
4lock: std.Mutex = .{},
4counter: usize = 0,5counter: usize = 0,
5event: ?*std.AutoResetEvent = null,6event: std.AutoResetEvent = .{},
67
7pub fn start(self: *WaitGroup) void {8pub fn start(self: *WaitGroup) void {
8 _ = @atomicRmw(usize, &self.counter, .Add, 1, .SeqCst);9 const held = self.lock.acquire();
10 defer held.release();
11
12 self.counter += 1;
9}13}
1014
11pub fn stop(self: *WaitGroup) void {15pub fn stop(self: *WaitGroup) void {
12 if (@atomicRmw(usize, &self.counter, .Sub, 1, .SeqCst) == 1)16 const held = self.lock.acquire();
13 if (@atomicRmw(?*std.AutoResetEvent, &self.event, .Xchg, null, .SeqCst)) |event|17 defer held.release();
14 event.set();18
19 self.counter -= 1;
20 if (self.counter == 0)
21 self.event.set();
15}22}
1623
17pub fn wait(self: *WaitGroup) void {24pub fn wait(self: *WaitGroup) void {
18 var event = std.AutoResetEvent{};25 {
19 @atomicStore(?*std.AutoResetEvent, &self.event, &event, .SeqCst);26 const held = self.lock.acquire();
20 if (@atomicLoad(usize, &self.counter, .SeqCst) != 0)27 defer held.release();
21 event.wait();28
29 if (self.counter == 0)
30 return;
31 }
32
33 self.event.wait();
22}34}