std.Thread: ResetEvent improvements (#11523)
* std: start removing redundant ResetEvents * src: fix other uses of std.Thread.ResetEvent * src: add builtin.sanitize_thread for tsan detection * atomic: add Atomic.fence for proper fencing with tsan * Thread: remove the other ResetEvent's and rewrite the current one * Thread: ResetEvent docs * zig fmt + WaitGroup.reset() fix * src: fix build issues for ResetEvent + tsan * Thread: ResetEvent tests * Thread: ResetEvent module doc * Atomic: replace llvm *p memory constraint with *m * panicking: handle spurious wakeups in futex.wait() when waiting for abort() * zig fmt
This commit is contained in:
@@ -10,10 +10,8 @@ const assert = std.debug.assert;
|
||||
const target = builtin.target;
|
||||
const Atomic = std.atomic.Atomic;
|
||||
|
||||
pub const AutoResetEvent = @import("Thread/AutoResetEvent.zig");
|
||||
pub const Futex = @import("Thread/Futex.zig");
|
||||
pub const ResetEvent = @import("Thread/ResetEvent.zig");
|
||||
pub const StaticResetEvent = @import("Thread/StaticResetEvent.zig");
|
||||
pub const Mutex = @import("Thread/Mutex.zig");
|
||||
pub const Semaphore = @import("Thread/Semaphore.zig");
|
||||
pub const Condition = @import("Thread/Condition.zig");
|
||||
@@ -1078,17 +1076,13 @@ test "setName, getName" {
|
||||
if (builtin.single_threaded) return error.SkipZigTest;
|
||||
|
||||
const Context = struct {
|
||||
start_wait_event: ResetEvent = undefined,
|
||||
test_done_event: ResetEvent = undefined,
|
||||
start_wait_event: ResetEvent = .{},
|
||||
test_done_event: ResetEvent = .{},
|
||||
thread_done_event: ResetEvent = .{},
|
||||
|
||||
done: std.atomic.Atomic(bool) = std.atomic.Atomic(bool).init(false),
|
||||
thread: Thread = undefined,
|
||||
|
||||
fn init(self: *@This()) !void {
|
||||
try self.start_wait_event.init();
|
||||
try self.test_done_event.init();
|
||||
}
|
||||
|
||||
pub fn run(ctx: *@This()) !void {
|
||||
// Wait for the main thread to have set the thread field in the context.
|
||||
ctx.start_wait_event.wait();
|
||||
@@ -1104,16 +1098,14 @@ test "setName, getName" {
|
||||
// Signal our test is done
|
||||
ctx.test_done_event.set();
|
||||
|
||||
while (!ctx.done.load(.SeqCst)) {
|
||||
std.time.sleep(5 * std.time.ns_per_ms);
|
||||
}
|
||||
// wait for the thread to property exit
|
||||
ctx.thread_done_event.wait();
|
||||
}
|
||||
};
|
||||
|
||||
var context = Context{};
|
||||
try context.init();
|
||||
|
||||
var thread = try spawn(.{}, Context.run, .{&context});
|
||||
|
||||
context.thread = thread;
|
||||
context.start_wait_event.set();
|
||||
context.test_done_event.wait();
|
||||
@@ -1139,16 +1131,14 @@ test "setName, getName" {
|
||||
},
|
||||
}
|
||||
|
||||
context.done.store(true, .SeqCst);
|
||||
context.thread_done_event.set();
|
||||
thread.join();
|
||||
}
|
||||
|
||||
test "std.Thread" {
|
||||
// Doesn't use testing.refAllDecls() since that would pull in the compileError spinLoopHint.
|
||||
_ = AutoResetEvent;
|
||||
_ = Futex;
|
||||
_ = ResetEvent;
|
||||
_ = StaticResetEvent;
|
||||
_ = Mutex;
|
||||
_ = Semaphore;
|
||||
_ = Condition;
|
||||
@@ -1163,9 +1153,7 @@ test "Thread.join" {
|
||||
if (builtin.single_threaded) return error.SkipZigTest;
|
||||
|
||||
var value: usize = 0;
|
||||
var event: ResetEvent = undefined;
|
||||
try event.init();
|
||||
defer event.deinit();
|
||||
var event = ResetEvent{};
|
||||
|
||||
const thread = try Thread.spawn(.{}, testIncrementNotify, .{ &value, &event });
|
||||
thread.join();
|
||||
@@ -1177,9 +1165,7 @@ test "Thread.detach" {
|
||||
if (builtin.single_threaded) return error.SkipZigTest;
|
||||
|
||||
var value: usize = 0;
|
||||
var event: ResetEvent = undefined;
|
||||
try event.init();
|
||||
defer event.deinit();
|
||||
var event = ResetEvent{};
|
||||
|
||||
const thread = try Thread.spawn(.{}, testIncrementNotify, .{ &value, &event });
|
||||
thread.detach();
|
||||
|
||||
Reference in New Issue
Block a user