diff options
| author | bors <bors@rust-lang.org> | 2020-10-01 13:21:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-10-01 13:21:34 +0000 |
| commit | 782013564efc06ef02614ba35a4e67dee4fcb8e7 (patch) | |
| tree | 2e905ff25153425fe0389ea1db074a72edcd7934 /library/std/src/sys/unix/futex.rs | |
| parent | 9cba260df0f1c67ea3690035cd5611a7465a1560 (diff) | |
| parent | 0b73fd7105db81a994a81b775a43bbdb1be3c76a (diff) | |
| download | rust-782013564efc06ef02614ba35a4e67dee4fcb8e7.tar.gz rust-782013564efc06ef02614ba35a4e67dee4fcb8e7.zip | |
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`.
Diffstat (limited to 'library/std/src/sys/unix/futex.rs')
| -rw-r--r-- | library/std/src/sys/unix/futex.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs new file mode 100644 index 00000000000..e6f0c48c59b --- /dev/null +++ b/library/std/src/sys/unix/futex.rs @@ -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, + ); + } +} |
