lib/simd/src/thread/wait.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const sys = @import("sys");
 3 
 4 pub const WaitWord = std.atomic.Value(u32);
 5 
 6 pub fn nanoSleep(nanoseconds: u64) bool {
 7     if (!sys.time.supportsAwakeClock()) return false;
 8     sys.time.sleepNanoseconds(nanoseconds);
 9     return true;
10 }
11 
12 pub fn blockUntilDifferent(
13     previous: u32,
14     word: *const WaitWord,
15 ) u32 {
16     return sys.thread.blockUntilDifferent(previous, word);
17 }
18 
19 pub fn wakeAll(word: *WaitWord) void {
20     sys.thread.wakeAll(word);
21 }
22 
23 const WakeContext = struct {
24     word: *WaitWord,
25     observed: *u32,
26 
27     fn wait(self: WakeContext) void {
28         self.observed.* = blockUntilDifferent(7, self.word);
29     }
30 };
31 
32 test "Highway wait word blocks until storage changes and wakes" {
33     if (!sys.thread.threadsSupported()) return error.SkipZigTest;
34     var word = WaitWord.init(7);
35     var observed: u32 = 0;
36     const handle = try sys.thread.spawn(WakeContext.wait, .{
37         WakeContext{ .word = &word, .observed = &observed },
38     });
39     _ = nanoSleep(std.time.ns_per_ms);
40     word.store(11, .release);
41     wakeAll(&word);
42     handle.join();
43     try std.testing.expectEqual(@as(u32, 11), observed);
44     try std.testing.expectEqual(@as(u32, 11), blockUntilDifferent(7, &word));
45 }