authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-23 20:35:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-23 20:49:38-07:00
logc2b1c8895334c4b597a665c2e8e29ce4a103f5b4
treeba71d00181c0e3dfd323e953f9a7d2b6e1301b2e
parent177377b6e356b34bbed40cadca596658d158af6b

std: fix compile errors introduced in previous commit


4 files changed, 33 insertions(+), 32 deletions(-)

lib/std/StaticResetEvent.zig+1-1
......@@ -105,7 +105,7 @@ pub const DebugEvent = struct {
105105 }
106106 }
107107
108 fn timedWait(ev: *DebugEvent, timeout: u64) TimedWaitResult {
108 pub fn timedWait(ev: *DebugEvent, timeout: u64) TimedWaitResult {
109109 switch (ev.state) {
110110 .unset => return .timed_out,
111111 .set => return .event_set,
lib/std/auto_reset_event.zig+21-22
......@@ -7,14 +7,15 @@ const std = @import("std.zig");
77const builtin = @import("builtin");
88const testing = std.testing;
99const assert = std.debug.assert;
10const StaticResetEvent = std.StaticResetEvent;
1011
11/// Similar to std.ResetEvent but on `set()` it also (atomically) does `reset()`.
12/// Unlike std.ResetEvent, `wait()` can only be called by one thread (MPSC-like).
12/// Similar to `StaticResetEvent` but on `set()` it also (atomically) does `reset()`.
13/// Unlike StaticResetEvent, `wait()` can only be called by one thread (MPSC-like).
1314pub const AutoResetEvent = struct {
1415 /// AutoResetEvent has 3 possible states:
1516 /// - UNSET: the AutoResetEvent is currently unset
1617 /// - SET: the AutoResetEvent was notified before a wait() was called
17 /// - <std.ResetEvent pointer>: there is an active waiter waiting for a notification.
18 /// - <StaticResetEvent pointer>: there is an active waiter waiting for a notification.
1819 ///
1920 /// When attempting to wait:
2021 /// if the event is unset, it registers a ResetEvent pointer to be notified when the event is set
......@@ -25,20 +26,20 @@ pub const AutoResetEvent = struct {
2526 /// if theres a waiting ResetEvent, then we unset the event and notify the ResetEvent
2627 ///
2728 /// This ensures that the event is automatically reset after a wait() has been issued
28 /// and avoids the race condition when using std.ResetEvent in the following scenario:
29 /// thread 1 | thread 2
30 /// std.ResetEvent.wait() |
31 /// | std.ResetEvent.set()
32 /// | std.ResetEvent.set()
33 /// std.ResetEvent.reset() |
34 /// std.ResetEvent.wait() | (missed the second .set() notification above)
29 /// and avoids the race condition when using StaticResetEvent in the following scenario:
30 /// thread 1 | thread 2
31 /// StaticResetEvent.wait() |
32 /// | StaticResetEvent.set()
33 /// | StaticResetEvent.set()
34 /// StaticResetEvent.reset() |
35 /// StaticResetEvent.wait() | (missed the second .set() notification above)
3536 state: usize = UNSET,
3637
3738 const UNSET = 0;
3839 const SET = 1;
3940
40 /// the minimum alignment for the `*std.ResetEvent` created by wait*()
41 const event_align = std.math.max(@alignOf(std.ResetEvent), 2);
41 /// the minimum alignment for the `*StaticResetEvent` created by wait*()
42 const event_align = std.math.max(@alignOf(StaticResetEvent), 2);
4243
4344 pub fn wait(self: *AutoResetEvent) void {
4445 self.waitFor(null) catch unreachable;
......@@ -49,12 +50,9 @@ pub const AutoResetEvent = struct {
4950 }
5051
5152 fn waitFor(self: *AutoResetEvent, timeout: ?u64) error{TimedOut}!void {
52 // lazily initialized std.ResetEvent
53 var reset_event: std.ResetEvent align(event_align) = undefined;
53 // lazily initialized StaticResetEvent
54 var reset_event: StaticResetEvent align(event_align) = undefined;
5455 var has_reset_event = false;
55 defer if (has_reset_event) {
56 reset_event.deinit();
57 };
5856
5957 var state = @atomicLoad(usize, &self.state, .SeqCst);
6058 while (true) {
......@@ -72,7 +70,7 @@ pub const AutoResetEvent = struct {
7270 // lazily initialize the ResetEvent if it hasn't been already
7371 if (!has_reset_event) {
7472 has_reset_event = true;
75 reset_event = std.ResetEvent.init();
73 reset_event = .{};
7674 }
7775
7876 // Since the AutoResetEvent currently isnt set,
......@@ -97,9 +95,10 @@ pub const AutoResetEvent = struct {
9795 };
9896
9997 // wait with a timeout and return if signalled via set()
100 if (reset_event.timedWait(timeout_ns)) |_| {
101 return;
102 } else |timed_out| {}
98 switch (reset_event.timedWait(timeout_ns)) {
99 .event_set => return,
100 .timed_out => {},
101 }
103102
104103 // If we timed out, we need to transition the AutoResetEvent back to UNSET.
105104 // If we don't, then when we return, a set() thread could observe a pointer to an invalid ResetEvent.
......@@ -164,7 +163,7 @@ pub const AutoResetEvent = struct {
164163 continue;
165164 }
166165
167 const reset_event = @intToPtr(*align(event_align) std.ResetEvent, state);
166 const reset_event = @intToPtr(*align(event_align) StaticResetEvent, state);
168167 reset_event.set();
169168 return;
170169 }
lib/std/fs/test.zig+2-1
......@@ -758,7 +758,8 @@ test "open file with exclusive lock twice, make sure it waits" {
758758 }
759759 };
760760
761 var evt = std.ResetEvent.init();
761 var evt: std.ResetEvent = undefined;
762 try evt.init();
762763 defer evt.deinit();
763764
764765 const t = try std.Thread.spawn(S.C{ .dir = &tmp.dir, .evt = &evt }, S.checkFn);
lib/std/mutex.zig+9-8
......@@ -10,7 +10,7 @@ const assert = std.debug.assert;
1010const windows = os.windows;
1111const testing = std.testing;
1212const SpinLock = std.SpinLock;
13const ResetEvent = std.ResetEvent;
13const StaticResetEvent = std.StaticResetEvent;
1414
1515/// Lock may be held only once. If the same thread tries to acquire
1616/// the same mutex twice, it deadlocks. This type supports static
......@@ -54,7 +54,7 @@ else if (builtin.link_libc or builtin.os.tag == .linux)
5454
5555 const Node = struct {
5656 next: ?*Node,
57 event: ResetEvent,
57 event: StaticResetEvent,
5858 };
5959
6060 pub fn tryAcquire(self: *Mutex) ?Held {
......@@ -90,11 +90,12 @@ else if (builtin.link_libc or builtin.os.tag == .linux)
9090 state = @atomicLoad(usize, &self.state, .Monotonic);
9191 }
9292
93 // create the ResetEvent node on the stack
93 // create the StaticResetEvent node on the stack
9494 // (faster than threadlocal on platforms like OSX)
95 var node: Node = undefined;
96 node.event = ResetEvent.init();
97 defer node.event.deinit();
95 var node: Node = .{
96 .next = undefined,
97 .event = .{},
98 };
9899
99100 // we've spun too long, try and add our node to the LIFO queue.
100101 // if the mutex becomes available in the process, try and grab it instead.
......@@ -284,7 +285,7 @@ const WindowsMutex = struct {
284285 fn acquireSlow(self: *WindowsMutex) Held {
285286 // try to use NT keyed events for blocking, falling back to spinlock if unavailable
286287 @setCold(true);
287 const handle = ResetEvent.Impl.Futex.getEventHandle() orelse return self.acquireSpinning();
288 const handle = StaticResetEvent.Impl.Futex.getEventHandle() orelse return self.acquireSpinning();
288289 const key = @ptrCast(*const c_void, &self.state.waiters);
289290
290291 while (true) : (SpinLock.loopHint(1)) {
......@@ -312,7 +313,7 @@ const WindowsMutex = struct {
312313 pub fn release(self: Held) void {
313314 // unlock without a rmw/cmpxchg instruction
314315 @atomicStore(u8, @ptrCast(*u8, &self.mutex.state.locked), 0, .Release);
315 const handle = ResetEvent.Impl.Futex.getEventHandle() orelse return;
316 const handle = StaticResetEvent.Impl.Futex.getEventHandle() orelse return;
316317 const key = @ptrCast(*const c_void, &self.mutex.state.waiters);
317318
318319 while (true) : (SpinLock.loopHint(1)) {