Skip to content

Commit a9e5c1a

Browse files
committed
std: unify id-based thread parking implementations
1 parent 0c0b403 commit a9e5c1a

File tree

19 files changed

+208
-231
lines changed

19 files changed

+208
-231
lines changed

library/std/src/sys/sgx/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub mod process;
3434
pub mod stdio;
3535
pub mod thread;
3636
pub mod thread_local_key;
37-
pub mod thread_parker;
37+
pub mod thread_parking;
3838
pub mod time;
3939

4040
mod condvar;

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ mod task_queue {
6565
/// execution. The signal is sent once all TLS destructors have finished at
6666
/// which point no new thread locals should be created.
6767
pub mod wait_notify {
68-
use super::super::thread_parker::Parker;
68+
use crate::mem::MaybeUninit;
6969
use crate::pin::Pin;
7070
use crate::sync::Arc;
71+
use crate::sys_common::thread_parking::Parker;
7172

7273
pub struct Notifier(Arc<Parker>);
7374

@@ -94,7 +95,18 @@ pub mod wait_notify {
9495
}
9596

9697
pub fn new() -> (Notifier, Waiter) {
97-
let inner = Arc::new(Parker::new_internal());
98+
// Safety:
99+
// Some other platforms (looking at you, UNIX!) require that the thread
100+
// parker is constructed in-place. This is just a noisy way of writing:
101+
// ```rust
102+
// let parker = Parker::new();
103+
// ```
104+
let parker = unsafe {
105+
let mut place = MaybeUninit::uninit();
106+
Parker::new(place.as_mut_ptr());
107+
place.assume_init()
108+
};
109+
let inner = Arc::new(parker);
98110
(Notifier(inner.clone()), Waiter(inner))
99111
}
100112
}

library/std/src/sys/sgx/thread_parker.rs

Lines changed: 0 additions & 107 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use super::abi::usercalls;
2+
use crate::io::ErrorKind;
3+
use crate::time::Duration;
4+
use fortanix_sgx_abi::{EV_UNPARK, WAIT_INDEFINITE};
5+
6+
pub type ThreadId = fortanix_sgx_abi::Tcs;
7+
8+
pub use super::abi::thread::current;
9+
10+
pub fn park() {
11+
usercalls::wait(EV_UNPARK, WAIT_INDEFINITE).unwrap();
12+
}
13+
14+
pub fn park_timeout(dur: Duration) {
15+
let timeout = u128::min(dur.as_nanos(), WAIT_INDEFINITE as u128 - 1) as u64;
16+
if let Err(e) = usercalls::wait(EV_UNPARK, timeout) {
17+
assert!(matches!(e.kind(), ErrorKind::TimedOut | ErrorKind::WouldBlock))
18+
}
19+
}
20+
21+
pub fn unpark(tid: ThreadId) {
22+
let _ = usercalls::send(EV_UNPARK, Some(tid));
23+
}

library/std/src/sys/unix/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub mod stdio;
4040
pub mod thread;
4141
pub mod thread_local_dtor;
4242
pub mod thread_local_key;
43-
pub mod thread_parker;
43+
pub mod thread_parking;
4444
pub mod time;
4545

4646
#[cfg(target_os = "espidf")]

library/std/src/sys/unix/thread_parker/netbsd.rs

Lines changed: 0 additions & 113 deletions
This file was deleted.

library/std/src/sys/unix/thread_parker/mod.rs renamed to library/std/src/sys/unix/thread_parking/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ cfg_if::cfg_if! {
2424
pub use darwin::Parker;
2525
} else if #[cfg(target_os = "netbsd")] {
2626
mod netbsd;
27-
pub use netbsd::Parker;
27+
pub use netbsd::{current, park, park_timeout, unpark, ThreadId};
2828
} else {
2929
mod pthread;
3030
pub use pthread::Parker;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#![cfg(target_os = "netbsd")]
2+
3+
use crate::ffi::{c_int, c_void};
4+
use crate::ptr::{null, null_mut};
5+
use crate::time::Duration;
6+
use libc::{_lwp_self, clockid_t, lwpid_t, time_t, timespec, CLOCK_MONOTONIC};
7+
8+
extern "C" {
9+
fn ___lwp_park60(
10+
clock_id: clockid_t,
11+
flags: c_int,
12+
ts: *mut timespec,
13+
unpark: lwpid_t,
14+
hint: *const c_void,
15+
unparkhint: *const c_void,
16+
) -> c_int;
17+
fn _lwp_unpark(lwp: lwpid_t, hint: *const c_void) -> c_int;
18+
}
19+
20+
pub type ThreadId = lwpid_t;
21+
22+
#[inline]
23+
pub fn current() -> ThreadId {
24+
unsafe { _lwp_self() }
25+
}
26+
27+
#[inline]
28+
pub fn park() {
29+
unsafe {
30+
___lwp_park60(0, 0, null_mut(), 0, null(), null());
31+
}
32+
}
33+
34+
pub fn park_timeout(dur: Duration) {
35+
let mut timeout = timespec {
36+
// Saturate so that the operation will definitely time out
37+
// (even if it is after the heat death of the universe).
38+
tv_sec: dur.as_secs().try_into().ok().unwrap_or(time_t::MAX),
39+
tv_nsec: dur.subsec_nanos().into(),
40+
};
41+
42+
// Timeout needs to be mutable since it is modified on NetBSD 9.0 and
43+
// above.
44+
unsafe {
45+
___lwp_park60(CLOCK_MONOTONIC, 0, &mut timeout, 0, null(), null());
46+
}
47+
}
48+
49+
#[inline]
50+
pub fn unpark(tid: ThreadId) {
51+
unsafe {
52+
_lwp_unpark(tid, null());
53+
}
54+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub mod stdio;
3333
pub mod thread;
3434
pub mod thread_local_dtor;
3535
pub mod thread_local_key;
36-
pub mod thread_parker;
36+
pub mod thread_parking;
3737
pub mod time;
3838
cfg_if::cfg_if! {
3939
if #[cfg(not(target_vendor = "uwp"))] {

library/std/src/sys_common/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub mod process;
3030
pub mod thread;
3131
pub mod thread_info;
3232
pub mod thread_local_dtor;
33-
pub mod thread_parker;
33+
pub mod thread_parking;
3434
pub mod wstr;
3535
pub mod wtf8;
3636

0 commit comments

Comments
 (0)