Auto merge of #76919 - fusion-engineering-forks:thread-parker, r=dtolnay
Use futex-based thread::park/unpark on Linux. This moves the parking/unparking logic out of `thread/mod.rs` into a module named `thread_parker` in `sys_common`. The current implementation is moved to `sys_common/thread_parker/generic.rs` and the new implementation using futexes is added in `sys_common/thread_parker/futex.rs`.
This commit is contained in:
commit
782013564e
7 changed files with 276 additions and 112 deletions
37
library/std/src/sys/unix/futex.rs
Normal file
37
library/std/src/sys/unix/futex.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
#![cfg(any(target_os = "linux", target_os = "android"))]
|
||||
|
||||
use crate::convert::TryInto;
|
||||
use crate::ptr::null;
|
||||
use crate::sync::atomic::AtomicI32;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
|
||||
let timespec = timeout.and_then(|d| {
|
||||
Some(libc::timespec {
|
||||
// Sleep forever if the timeout is longer than fits in a timespec.
|
||||
tv_sec: d.as_secs().try_into().ok()?,
|
||||
// This conversion never truncates, as subsec_nanos is always <1e9.
|
||||
tv_nsec: d.subsec_nanos() as _,
|
||||
})
|
||||
});
|
||||
unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_futex,
|
||||
futex as *const AtomicI32,
|
||||
libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG,
|
||||
expected,
|
||||
timespec.as_ref().map_or(null(), |d| d as *const libc::timespec),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn futex_wake(futex: &AtomicI32) {
|
||||
unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_futex,
|
||||
futex as *const AtomicI32,
|
||||
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@ pub mod env;
|
|||
pub mod ext;
|
||||
pub mod fd;
|
||||
pub mod fs;
|
||||
pub mod futex;
|
||||
pub mod io;
|
||||
#[cfg(target_os = "l4re")]
|
||||
mod l4re;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue