authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-09-24 16:15:06-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-09-26 12:35:14-07:00
log04e694ad116ad2706328c13ce3643347330a861f
tree9aa8a254e980c73733b07dabbb5c6d4d0905a546
parent085cc54aadb327b9910be2c72b31ea046e7e8f52

move std.time.sleep to std.Thread.sleep


2 files changed, 81 insertions(+), 78 deletions(-)

lib/std/Thread.zig+77
...@@ -22,6 +22,83 @@ pub const WaitGroup = @import("Thread/WaitGroup.zig");...@@ -22,6 +22,83 @@ pub const WaitGroup = @import("Thread/WaitGroup.zig");
2222
23pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;23pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;
2424
25/// Spurious wakeups are possible and no precision of timing is guaranteed.
26pub fn sleep(nanoseconds: u64) void {
27 if (builtin.os.tag == .windows) {
28 const big_ms_from_ns = nanoseconds / std.time.ns_per_ms;
29 const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
30 windows.kernel32.Sleep(ms);
31 return;
32 }
33
34 if (builtin.os.tag == .wasi) {
35 const w = std.os.wasi;
36 const userdata: w.userdata_t = 0x0123_45678;
37 const clock: w.subscription_clock_t = .{
38 .id = .MONOTONIC,
39 .timeout = nanoseconds,
40 .precision = 0,
41 .flags = 0,
42 };
43 const in: w.subscription_t = .{
44 .userdata = userdata,
45 .u = .{
46 .tag = .CLOCK,
47 .u = .{ .clock = clock },
48 },
49 };
50
51 var event: w.event_t = undefined;
52 var nevents: usize = undefined;
53 _ = w.poll_oneoff(&in, &event, 1, &nevents);
54 return;
55 }
56
57 if (builtin.os.tag == .uefi) {
58 const boot_services = std.os.uefi.system_table.boot_services.?;
59 const us_from_ns = nanoseconds / std.time.ns_per_us;
60 const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
61 _ = boot_services.stall(us);
62 return;
63 }
64
65 const s = nanoseconds / std.time.ns_per_s;
66 const ns = nanoseconds % std.time.ns_per_s;
67
68 // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
69 // since Linux 2.6 and glibc 2.1 anyway.
70 if (builtin.os.tag == .linux) {
71 const linux = std.os.linux;
72
73 var req: linux.timespec = .{
74 .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
75 .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
76 };
77 var rem: linux.timespec = undefined;
78
79 while (true) {
80 switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
81 .SUCCESS => return,
82 .INTR => {
83 req = rem;
84 continue;
85 },
86 .FAULT,
87 .INVAL,
88 .OPNOTSUPP,
89 => unreachable,
90 else => return,
91 }
92 }
93 }
94
95 posix.nanosleep(s, ns);
96}
97
98test sleep {
99 sleep(1);
100}
101
25const Thread = @This();102const Thread = @This();
26const Impl = if (native_os == .windows)103const Impl = if (native_os == .windows)
27 WindowsThreadImpl104 WindowsThreadImpl
lib/std/time.zig+4-78
...@@ -8,82 +8,8 @@ const posix = std.posix;...@@ -8,82 +8,8 @@ const posix = std.posix;
88
9pub const epoch = @import("time/epoch.zig");9pub const epoch = @import("time/epoch.zig");
1010
11/// Spurious wakeups are possible and no precision of timing is guaranteed.11/// Deprecated: moved to std.Thread.sleep
12pub fn sleep(nanoseconds: u64) void {12pub const sleep = std.Thread.sleep;
13 if (builtin.os.tag == .windows) {
14 const big_ms_from_ns = nanoseconds / ns_per_ms;
15 const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
16 windows.kernel32.Sleep(ms);
17 return;
18 }
19
20 if (builtin.os.tag == .wasi) {
21 const w = std.os.wasi;
22 const userdata: w.userdata_t = 0x0123_45678;
23 const clock: w.subscription_clock_t = .{
24 .id = .MONOTONIC,
25 .timeout = nanoseconds,
26 .precision = 0,
27 .flags = 0,
28 };
29 const in: w.subscription_t = .{
30 .userdata = userdata,
31 .u = .{
32 .tag = .CLOCK,
33 .u = .{ .clock = clock },
34 },
35 };
36
37 var event: w.event_t = undefined;
38 var nevents: usize = undefined;
39 _ = w.poll_oneoff(&in, &event, 1, &nevents);
40 return;
41 }
42
43 if (builtin.os.tag == .uefi) {
44 const boot_services = std.os.uefi.system_table.boot_services.?;
45 const us_from_ns = nanoseconds / ns_per_us;
46 const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
47 _ = boot_services.stall(us);
48 return;
49 }
50
51 const s = nanoseconds / ns_per_s;
52 const ns = nanoseconds % ns_per_s;
53
54 // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
55 // since Linux 2.6 and glibc 2.1 anyway.
56 if (builtin.os.tag == .linux) {
57 const linux = std.os.linux;
58
59 var req: linux.timespec = .{
60 .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
61 .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
62 };
63 var rem: linux.timespec = undefined;
64
65 while (true) {
66 switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
67 .SUCCESS => return,
68 .INTR => {
69 req = rem;
70 continue;
71 },
72 .FAULT,
73 .INVAL,
74 .OPNOTSUPP,
75 => unreachable,
76 else => return,
77 }
78 }
79 }
80
81 posix.nanosleep(s, ns);
82}
83
84test sleep {
85 sleep(1);
86}
8713
88/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.14/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.
89/// Precision of timing depends on the hardware and operating system.15/// Precision of timing depends on the hardware and operating system.
...@@ -155,7 +81,7 @@ test milliTimestamp {...@@ -155,7 +81,7 @@ test milliTimestamp {
155 const margin = ns_per_ms * 50;81 const margin = ns_per_ms * 50;
15682
157 const time_0 = milliTimestamp();83 const time_0 = milliTimestamp();
158 sleep(ns_per_ms);84 std.Thread.sleep(ns_per_ms);
159 const time_1 = milliTimestamp();85 const time_1 = milliTimestamp();
160 const interval = time_1 - time_0;86 const interval = time_1 - time_0;
161 try testing.expect(interval > 0);87 try testing.expect(interval > 0);
...@@ -359,7 +285,7 @@ test Timer {...@@ -359,7 +285,7 @@ test Timer {
359 const margin = ns_per_ms * 150;285 const margin = ns_per_ms * 150;
360286
361 var timer = try Timer.start();287 var timer = try Timer.start();
362 sleep(10 * ns_per_ms);288 std.Thread.sleep(10 * ns_per_ms);
363 const time_0 = timer.read();289 const time_0 = timer.read();
364 try testing.expect(time_0 > 0);290 try testing.expect(time_0 > 0);
365 // Tests should not depend on timings: skip test if outside margin.291 // Tests should not depend on timings: skip test if outside margin.