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

This commit is contained in:
Andrew Kelley
2024-09-24 16:15:06 -07:00
parent 085cc54aad
commit 04e694ad11
2 changed files with 81 additions and 78 deletions

View File

@@ -22,6 +22,83 @@ pub const WaitGroup = @import("Thread/WaitGroup.zig");
pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;
/// Spurious wakeups are possible and no precision of timing is guaranteed.
pub fn sleep(nanoseconds: u64) void {
if (builtin.os.tag == .windows) {
const big_ms_from_ns = nanoseconds / std.time.ns_per_ms;
const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
windows.kernel32.Sleep(ms);
return;
}
if (builtin.os.tag == .wasi) {
const w = std.os.wasi;
const userdata: w.userdata_t = 0x0123_45678;
const clock: w.subscription_clock_t = .{
.id = .MONOTONIC,
.timeout = nanoseconds,
.precision = 0,
.flags = 0,
};
const in: w.subscription_t = .{
.userdata = userdata,
.u = .{
.tag = .CLOCK,
.u = .{ .clock = clock },
},
};
var event: w.event_t = undefined;
var nevents: usize = undefined;
_ = w.poll_oneoff(&in, &event, 1, &nevents);
return;
}
if (builtin.os.tag == .uefi) {
const boot_services = std.os.uefi.system_table.boot_services.?;
const us_from_ns = nanoseconds / std.time.ns_per_us;
const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
_ = boot_services.stall(us);
return;
}
const s = nanoseconds / std.time.ns_per_s;
const ns = nanoseconds % std.time.ns_per_s;
// Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
// since Linux 2.6 and glibc 2.1 anyway.
if (builtin.os.tag == .linux) {
const linux = std.os.linux;
var req: linux.timespec = .{
.sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
.nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
};
var rem: linux.timespec = undefined;
while (true) {
switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
.SUCCESS => return,
.INTR => {
req = rem;
continue;
},
.FAULT,
.INVAL,
.OPNOTSUPP,
=> unreachable,
else => return,
}
}
}
posix.nanosleep(s, ns);
}
test sleep {
sleep(1);
}
const Thread = @This();
const Impl = if (native_os == .windows)
WindowsThreadImpl

View File

@@ -8,82 +8,8 @@ const posix = std.posix;
pub const epoch = @import("time/epoch.zig");
/// Spurious wakeups are possible and no precision of timing is guaranteed.
pub fn sleep(nanoseconds: u64) void {
if (builtin.os.tag == .windows) {
const big_ms_from_ns = nanoseconds / ns_per_ms;
const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
windows.kernel32.Sleep(ms);
return;
}
if (builtin.os.tag == .wasi) {
const w = std.os.wasi;
const userdata: w.userdata_t = 0x0123_45678;
const clock: w.subscription_clock_t = .{
.id = .MONOTONIC,
.timeout = nanoseconds,
.precision = 0,
.flags = 0,
};
const in: w.subscription_t = .{
.userdata = userdata,
.u = .{
.tag = .CLOCK,
.u = .{ .clock = clock },
},
};
var event: w.event_t = undefined;
var nevents: usize = undefined;
_ = w.poll_oneoff(&in, &event, 1, &nevents);
return;
}
if (builtin.os.tag == .uefi) {
const boot_services = std.os.uefi.system_table.boot_services.?;
const us_from_ns = nanoseconds / ns_per_us;
const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
_ = boot_services.stall(us);
return;
}
const s = nanoseconds / ns_per_s;
const ns = nanoseconds % ns_per_s;
// Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
// since Linux 2.6 and glibc 2.1 anyway.
if (builtin.os.tag == .linux) {
const linux = std.os.linux;
var req: linux.timespec = .{
.sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
.nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
};
var rem: linux.timespec = undefined;
while (true) {
switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
.SUCCESS => return,
.INTR => {
req = rem;
continue;
},
.FAULT,
.INVAL,
.OPNOTSUPP,
=> unreachable,
else => return,
}
}
}
posix.nanosleep(s, ns);
}
test sleep {
sleep(1);
}
/// Deprecated: moved to std.Thread.sleep
pub const sleep = std.Thread.sleep;
/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.
/// Precision of timing depends on the hardware and operating system.
@@ -155,7 +81,7 @@ test milliTimestamp {
const margin = ns_per_ms * 50;
const time_0 = milliTimestamp();
sleep(ns_per_ms);
std.Thread.sleep(ns_per_ms);
const time_1 = milliTimestamp();
const interval = time_1 - time_0;
try testing.expect(interval > 0);
@@ -359,7 +285,7 @@ test Timer {
const margin = ns_per_ms * 150;
var timer = try Timer.start();
sleep(10 * ns_per_ms);
std.Thread.sleep(10 * ns_per_ms);
const time_0 = timer.read();
try testing.expect(time_0 > 0);
// Tests should not depend on timings: skip test if outside margin.