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