| ... | ... | @@ -3,6 +3,7 @@ const builtin = @import("builtin"); |
| 3 | 3 | const Os = builtin.Os; |
| 4 | 4 | const debug = std.debug; |
| 5 | 5 | const testing = std.testing; |
| 6 | const math = std.math; |
| 6 | 7 | |
| 7 | 8 | const windows = std.os.windows; |
| 8 | 9 | const linux = std.os.linux; |
| ... | ... | @@ -30,16 +31,26 @@ pub fn sleep(nanoseconds: u64) void { |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | pub fn posixSleep(seconds: u63, nanoseconds: u63) void { |
| 33 | | var req = posix.timespec{ |
| 34 | | .tv_sec = @intCast(isize, seconds), |
| 35 | | .tv_nsec = @intCast(isize, nanoseconds), |
| 36 | | }; |
| 34 | var req: posix.timespec = undefined; |
| 37 | 35 | var rem: posix.timespec = undefined; |
| 36 | |
| 37 | var req_sec = seconds; |
| 38 | var req_nsec = nanoseconds; |
| 39 | |
| 38 | 40 | while (true) { |
| 41 | req.tv_sec = math.min(math.maxInt(isize), req_sec); |
| 42 | req.tv_nsec = @intCast(isize, req_nsec); |
| 43 | |
| 44 | req_sec -= @intCast(u63, req.tv_sec); |
| 45 | req_nsec = 0; |
| 46 | |
| 39 | 47 | const ret_val = posix.nanosleep(&req, &rem); |
| 40 | 48 | const err = posix.getErrno(ret_val); |
| 41 | | if (err == 0) return; |
| 42 | 49 | switch (err) { |
| 50 | 0 => { |
| 51 | // If there's still time to wait keep running the loop |
| 52 | if (req_sec == 0 and req_nsec == 0) return; |
| 53 | }, |
| 43 | 54 | posix.EFAULT => unreachable, |
| 44 | 55 | posix.EINVAL => { |
| 45 | 56 | // Sometimes Darwin returns EINVAL for no reason. |
| ... | ... | @@ -47,7 +58,8 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void { |
| 47 | 58 | return; |
| 48 | 59 | }, |
| 49 | 60 | posix.EINTR => { |
| 50 | | req = rem; |
| 61 | req_sec += @intCast(u63, rem.tv_sec); |
| 62 | req_nsec = @intCast(u63, rem.tv_nsec); |
| 51 | 63 | continue; |
| 52 | 64 | }, |
| 53 | 65 | else => return, |