Skip to content

Commit 4238e5e

Browse files
committed
sleep_until: add platform specific implementations
Except for unix they are all copies of the existing non platform specific implementation. This is the only way since tidy does not allow `#[cfg(target_os = ` in src/thread/mod.rs. Once this is merged more specializations will follow.
1 parent 35f6036 commit 4238e5e

File tree

15 files changed

+200
-20
lines changed

15 files changed

+200
-20
lines changed

library/std/src/sys/pal/hermit/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::hermit_abi;
44
use crate::ffi::CStr;
55
use crate::mem::ManuallyDrop;
66
use crate::num::NonZero;
7-
use crate::time::Duration;
7+
use crate::time::{Duration, Instant};
88
use crate::{io, ptr};
99

1010
pub type Tid = hermit_abi::Tid;
@@ -86,6 +86,14 @@ impl Thread {
8686
}
8787
}
8888

89+
pub fn sleep_until(deadline: Instant) {
90+
let now = Instant::now();
91+
92+
if let Some(delay) = deadline.checked_duration_since(now) {
93+
Self::sleep(delay);
94+
}
95+
}
96+
8997
pub fn join(self) {
9098
unsafe {
9199
let _ = hermit_abi::join(self.tid);

library/std/src/sys/pal/itron/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::mem::ManuallyDrop;
1010
use crate::num::NonZero;
1111
use crate::ptr::NonNull;
1212
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
13-
use crate::time::Duration;
13+
use crate::time::{Duration, Instant};
1414
use crate::{hint, io};
1515

1616
pub struct Thread {
@@ -205,6 +205,14 @@ impl Thread {
205205
}
206206
}
207207

208+
pub fn sleep_until(deadline: Instant) {
209+
let now = Instant::now();
210+
211+
if let Some(delay) = deadline.checked_duration_since(now) {
212+
Self::sleep(delay);
213+
}
214+
}
215+
208216
pub fn join(self) {
209217
// Safety: `ThreadInner` is alive at this point
210218
let inner = unsafe { self.p_inner.as_ref() };

library/std/src/sys/pal/sgx/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::unsupported;
55
use crate::ffi::CStr;
66
use crate::io;
77
use crate::num::NonZero;
8-
use crate::time::Duration;
8+
use crate::time::{Duration, Instant};
99

1010
pub struct Thread(task_queue::JoinHandle);
1111

@@ -132,6 +132,14 @@ impl Thread {
132132
usercalls::wait_timeout(0, dur, || true);
133133
}
134134

135+
pub fn sleep_until(deadline: Instant) {
136+
let now = Instant::now();
137+
138+
if let Some(delay) = deadline.checked_duration_since(now) {
139+
Self::sleep(delay);
140+
}
141+
}
142+
135143
pub fn join(self) {
136144
self.0.wait();
137145
}

library/std/src/sys/pal/teeos/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ffi::CStr;
22
use crate::mem::{self, ManuallyDrop};
33
use crate::num::NonZero;
44
use crate::sys::os;
5-
use crate::time::Duration;
5+
use crate::time::{Duration, Instant};
66
use crate::{cmp, io, ptr};
77

88
pub const DEFAULT_MIN_STACK_SIZE: usize = 8 * 1024;
@@ -109,6 +109,14 @@ impl Thread {
109109
}
110110
}
111111

112+
pub fn sleep_until(deadline: Instant) {
113+
let now = Instant::now();
114+
115+
if let Some(delay) = deadline.checked_duration_since(now) {
116+
Self::sleep(delay);
117+
}
118+
}
119+
112120
/// must join, because no pthread_detach supported
113121
pub fn join(self) {
114122
let id = self.into_id();

library/std/src/sys/pal/uefi/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::ffi::CStr;
33
use crate::io;
44
use crate::num::NonZero;
55
use crate::ptr::NonNull;
6-
use crate::time::Duration;
6+
use crate::time::{Duration, Instant};
77

88
pub struct Thread(!);
99

@@ -39,6 +39,14 @@ impl Thread {
3939
}
4040
}
4141

42+
pub fn sleep_until(deadline: Instant) {
43+
let now = Instant::now();
44+
45+
if let Some(delay) = deadline.checked_duration_since(now) {
46+
Self::sleep(delay);
47+
}
48+
}
49+
4250
pub fn join(self) {
4351
self.0
4452
}

library/std/src/sys/pal/unix/thread.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::sys::weak::dlsym;
66
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
77
use crate::sys::weak::weak;
88
use crate::sys::{os, stack_overflow};
9-
use crate::time::Duration;
9+
use crate::time::{Duration, Instant};
1010
use crate::{cmp, io, ptr};
1111
#[cfg(not(any(
1212
target_os = "l4re",
@@ -296,6 +296,63 @@ impl Thread {
296296
}
297297
}
298298

299+
// Any unix that has clock_nanosleep
300+
#[cfg(any(
301+
target_os = "freebsd",
302+
target_os = "netbsd",
303+
target_os = "linux",
304+
target_os = "android",
305+
target_os = "solaris",
306+
target_os = "illumos",
307+
target_os = "dragonfly",
308+
target_os = "hurd",
309+
target_os = "fuchsia",
310+
target_os = "vxworks",
311+
))]
312+
pub fn sleep_until(deadline: Instant) {
313+
let mut ts = deadline
314+
.into_inner()
315+
.into_timespec()
316+
.to_timespec()
317+
.expect("Timespec is narrower then libc::timespec thus conversion can't fail");
318+
let ts_ptr = &mut ts as *mut _;
319+
320+
// If we're awoken with a signal and the return value is -1
321+
// clock_nanosleep needs to be called again.
322+
unsafe {
323+
while libc::clock_nanosleep(libc::CLOCK_MONOTONIC, libc::TIMER_ABSTIME, ts_ptr, ts_ptr)
324+
== -1
325+
{
326+
assert_eq!(
327+
os::errno(),
328+
libc::EINTR,
329+
"clock nanosleep should only return an error if interrupted"
330+
);
331+
}
332+
}
333+
}
334+
335+
// Any unix that does not have clock_nanosleep
336+
#[cfg(not(any(
337+
target_os = "freebsd",
338+
target_os = "netbsd",
339+
target_os = "linux",
340+
target_os = "android",
341+
target_os = "solaris",
342+
target_os = "illumos",
343+
target_os = "dragonfly",
344+
target_os = "hurd",
345+
target_os = "fuchsia",
346+
target_os = "vxworks",
347+
)))]
348+
pub fn sleep_until(deadline: Instant) {
349+
let now = Instant::now();
350+
351+
if let Some(delay) = deadline.checked_duration_since(now) {
352+
Self::sleep(delay);
353+
}
354+
}
355+
299356
pub fn join(self) {
300357
let id = self.into_id();
301358
let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };

library/std/src/sys/pal/unix/time.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,13 @@ impl Instant {
291291
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
292292
Some(Instant { t: self.t.checked_sub_duration(other)? })
293293
}
294+
295+
// reason for allow(unused): this is needed by the `sleep_until` implementation
296+
// for some unix platforms not all.
297+
#[allow(unused)]
298+
pub(crate) fn into_timespec(self) -> Timespec {
299+
self.t
300+
}
294301
}
295302

296303
impl fmt::Debug for Instant {

library/std/src/sys/pal/unsupported/thread.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ impl Thread {
2626
panic!("can't sleep");
2727
}
2828

29+
pub fn sleep_until(_deadline: Instant) {
30+
panic!("can't sleep");
31+
}
32+
2933
pub fn join(self) {
3034
self.0
3135
}

library/std/src/sys/pal/wasi/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use crate::ffi::CStr;
44
use crate::num::NonZero;
5-
use crate::time::Duration;
5+
use crate::time::{Duration, Instant};
66
use crate::{io, mem};
77

88
cfg_if::cfg_if! {
@@ -171,6 +171,14 @@ impl Thread {
171171
}
172172
}
173173

174+
pub fn sleep_until(deadline: Instant) {
175+
let now = Instant::now();
176+
177+
if let Some(delay) = deadline.checked_duration_since(now) {
178+
Self::sleep(delay);
179+
}
180+
}
181+
174182
pub fn join(self) {
175183
cfg_if::cfg_if! {
176184
if #[cfg(target_feature = "atomics")] {

library/std/src/sys/pal/wasm/atomics/thread.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ffi::CStr;
22
use crate::io;
33
use crate::num::NonZero;
44
use crate::sys::unsupported;
5-
use crate::time::Duration;
5+
use crate::time::{Duration, Instant};
66

77
pub struct Thread(!);
88

@@ -41,6 +41,14 @@ impl Thread {
4141
}
4242
}
4343

44+
pub fn sleep_until(deadline: Instant) {
45+
let now = Instant::now();
46+
47+
if let Some(delay) = deadline.checked_duration_since(now) {
48+
Self::sleep(delay);
49+
}
50+
}
51+
4452
pub fn join(self) {}
4553
}
4654

0 commit comments

Comments
 (0)