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 @@
11const std = @import("std");
22const WaitGroup = @This();
33
4lock: std.Mutex = .{},
45counter: usize = 0,
5event: ?*std.AutoResetEvent = null,
6event: std.AutoResetEvent = .{},
67
78pub 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;
913}
1014
1115pub fn stop(self: *WaitGroup) void {
12 if (@atomicRmw(usize, &self.counter, .Sub, 1, .SeqCst) == 1)
13 if (@atomicRmw(?*std.AutoResetEvent, &self.event, .Xchg, null, .SeqCst)) |event|
14 event.set();
16 const held = self.lock.acquire();
17 defer held.release();
18
19 self.counter -= 1;
20 if (self.counter == 0)
21 self.event.set();
1522}
1623
1724pub fn wait(self: *WaitGroup) void {
18 var event = std.AutoResetEvent{};
19 @atomicStore(?*std.AutoResetEvent, &self.event, &event, .SeqCst);
20 if (@atomicLoad(usize, &self.counter, .SeqCst) != 0)
21 event.wait();
25 {
26 const held = self.lock.acquire();
27 defer held.release();
28
29 if (self.counter == 0)
30 return;
31 }
32
33 self.event.wait();
2234}