| ... | @@ -2719,7 +2719,13 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2719,7 +2719,13 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2719 | } | 2719 | } |
| 2720 | } | 2720 | } |
| 2721 | | 2721 | |
| 2722 | var delay_interval: windows.LARGE_INTEGER = timeoutToWindowsInterval(timeout); | 2722 | const deadline: ?Io.Clock.Timestamp = timeout.toDeadline(ioBasic(t)) catch |err| switch (err) { |
| | 2723 | error.Unexpected => deadline: { |
| | 2724 | recoverableOsBugDetected(); |
| | 2725 | break :deadline .{ .raw = .{ .nanoseconds = 0 }, .clock = .awake }; |
| | 2726 | }, |
| | 2727 | error.UnsupportedClock => |e| return e, |
| | 2728 | }; |
| 2723 | | 2729 | |
| 2724 | while (true) { | 2730 | while (true) { |
| 2725 | var any_pending = false; | 2731 | var any_pending = false; |
| ... | @@ -2741,6 +2747,16 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa | ... | @@ -2741,6 +2747,16 @@ fn batchWaitWindows(t: *Threaded, b: *Io.Batch, timeout: Io.Timeout) Io.Batch.Wa |
| 2741 | } | 2747 | } |
| 2742 | if (b.user.complete_head != complete_tail) return; | 2748 | if (b.user.complete_head != complete_tail) return; |
| 2743 | if (!any_pending) return; | 2749 | if (!any_pending) return; |
| | 2750 | var delay_interval: windows.LARGE_INTEGER = interval: { |
| | 2751 | const d = deadline orelse break :interval std.math.minInt(windows.LARGE_INTEGER); |
| | 2752 | break :interval t.deadlineToWindowsInterval(d) catch |err| switch (err) { |
| | 2753 | error.UnsupportedClock => |e| return e, |
| | 2754 | error.Unexpected => { |
| | 2755 | recoverableOsBugDetected(); |
| | 2756 | break :interval -1; |
| | 2757 | }, |
| | 2758 | }; |
| | 2759 | }; |
| 2744 | const alertable_syscall = try AlertableSyscall.start(); | 2760 | const alertable_syscall = try AlertableSyscall.start(); |
| 2745 | const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval); | 2761 | const delay_rc = windows.ntdll.NtDelayExecution(windows.TRUE, &delay_interval); |
| 2746 | alertable_syscall.finish(); | 2762 | alertable_syscall.finish(); |
| ... | @@ -16784,19 +16800,18 @@ fn park(opt_deadline: ?Io.Clock.Timestamp, addr_hint: ?*const anyopaque) error{T | ... | @@ -16784,19 +16800,18 @@ fn park(opt_deadline: ?Io.Clock.Timestamp, addr_hint: ?*const anyopaque) error{T |
| 16784 | } | 16800 | } |
| 16785 | } | 16801 | } |
| 16786 | | 16802 | |
| 16787 | fn timeoutToWindowsInterval(timeout: Io.Timeout) windows.LARGE_INTEGER { | 16803 | fn deadlineToWindowsInterval(t: *Io.Threaded, deadline: Io.Clock.Timestamp) Io.Clock.Error!windows.LARGE_INTEGER { |
| 16788 | switch (timeout) { | 16804 | // ntdll only supports two combinations: |
| 16789 | .none => { | 16805 | // * real-time (`.real`) sleeps with absolute deadlines |
| 16790 | return std.math.minInt(windows.LARGE_INTEGER); // infinite timeout | 16806 | // * monotonic (`.awake`/`.boot`) sleeps with relative durations |
| 16791 | }, | 16807 | switch (deadline.clock) { |
| 16792 | .deadline => |deadline| { | 16808 | .cpu_process, .cpu_thread => unreachable, // cannot sleep for CPU time |
| 16793 | const nanoseconds = deadline.raw.nanoseconds; | 16809 | .real => { |
| 16794 | return @intCast(@divTrunc(nanoseconds, 100)); | 16810 | return @intCast(@max(@divTrunc(deadline.raw.nanoseconds, 100), 0)); |
| 16795 | }, | 16811 | }, |
| 16796 | .duration => |duration| { | 16812 | .awake, .boot => { |
| 16797 | const now_timestamp = nowWindows(duration.clock) catch unreachable; | 16813 | const duration = try deadline.durationFromNow(ioBasic(t)); |
| 16798 | const deadline_ns = now_timestamp.nanoseconds + duration.raw.nanoseconds; | 16814 | return @intCast(@min(@divTrunc(-duration.raw.nanoseconds, 100), -1)); |
| 16799 | return @intCast(@divTrunc(deadline_ns, 100)); | | |
| 16800 | }, | 16815 | }, |
| 16801 | } | 16816 | } |
| 16802 | } | 16817 | } |