Skip to content

Commit 93e4ce0

Browse files
committed
adds specialized impl for sleep_until for windows
1 parent 0de580b commit 93e4ce0

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

library/std/src/sys/windows/thread.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::sys::c;
88
use crate::sys::handle::Handle;
99
use crate::sys::stack_overflow;
1010
use crate::sys_common::FromInner;
11-
use crate::time::Duration;
11+
use crate::time::{Duration, Instant};
1212

1313
use core::ffi::c_void;
1414

@@ -102,11 +102,22 @@ impl Thread {
102102
}
103103

104104
pub fn sleep_until(deadline: Instant) {
105-
let now = Instant::now();
106-
107-
if let Some(delay) = deadline.checked_duration_since(now) {
108-
sleep(delay);
105+
fn high_precision_sleep(deadline: Instant) -> Result<(), ()> {
106+
let timer = WaitableTimer::high_resolution()?;
107+
timer.set_deadline(deadline.into_inner())?;
108+
timer.wait()
109+
}
110+
// Attempt to use high-precision sleep (Windows 10, version 1803+).
111+
// On error fallback to the standard `Sleep` function.
112+
// Also preserves the zero duration behaviour of `Sleep`.
113+
if high_precision_sleep(deadline).is_ok() {
114+
return;
109115
}
116+
117+
let now = Instant::now();
118+
if let Some(dur) = deadline.checked_duration_since(now) {
119+
unsafe { c::Sleep(super::dur2timeout(dur)) }
120+
};
110121
}
111122

112123
pub fn handle(&self) -> &Handle {

library/std/src/sys/windows/time.rs

+6
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ impl WaitableTimer {
250250
let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) };
251251
if result != 0 { Ok(()) } else { Err(()) }
252252
}
253+
pub fn set_deadline(&self, deadline: Instant) -> Result<(), ()> {
254+
// Convert the Instant to a format similar to FILETIME.
255+
let time = checked_dur2intervals(&deadline.t).ok_or(())?;
256+
let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) };
257+
if result != 0 { Ok(()) } else { Err(()) }
258+
}
253259
pub fn wait(&self) -> Result<(), ()> {
254260
let result = unsafe { c::WaitForSingleObject(self.handle, c::INFINITE) };
255261
if result != c::WAIT_FAILED { Ok(()) } else { Err(()) }

0 commit comments

Comments
 (0)