Rollup merge of #127807 - ChrisDenton:win-parking, r=joboet
Use futex.rs for Windows thread parking If I'm not overlooking anything then the Windows 10+ thread parking implementation is practically the same as the futex.rs implementation. So we may as well use the same implementation for both. The old version is still kept around for Windows 7 support. r? ````@joboet```` if you wouldn't mind double checking I've not missed something
This commit is contained in:
commit
446e0177ec
8 changed files with 38 additions and 25 deletions
|
|
@ -3,6 +3,11 @@ use crate::ptr::null;
|
|||
use crate::sync::atomic::AtomicU32;
|
||||
use crate::time::Duration;
|
||||
|
||||
/// An atomic for use as a futex that is at least 8-bits but may be larger.
|
||||
pub type SmallAtomic = AtomicU32;
|
||||
/// Must be the underlying type of SmallAtomic
|
||||
pub type SmallPrimitive = u32;
|
||||
|
||||
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
|
||||
// Calculate the timeout as a relative timespec.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@
|
|||
use crate::sync::atomic::AtomicU32;
|
||||
use crate::time::Duration;
|
||||
|
||||
/// An atomic for use as a futex that is at least 8-bits but may be larger.
|
||||
pub type SmallAtomic = AtomicU32;
|
||||
/// Must be the underlying type of SmallAtomic
|
||||
pub type SmallPrimitive = u32;
|
||||
|
||||
/// Wait for a futex_wake operation to wake us.
|
||||
///
|
||||
/// Returns directly if the futex doesn't hold the expected value.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ use core::arch::wasm64 as wasm;
|
|||
use crate::sync::atomic::AtomicU32;
|
||||
use crate::time::Duration;
|
||||
|
||||
/// An atomic for use as a futex that is at least 8-bits but may be larger.
|
||||
pub type SmallAtomic = AtomicU32;
|
||||
/// Must be the underlying type of SmallAtomic
|
||||
pub type SmallPrimitive = u32;
|
||||
|
||||
/// Wait for a futex_wake operation to wake us.
|
||||
///
|
||||
/// Returns directly if the futex doesn't hold the expected value.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ use core::sync::atomic::{
|
|||
};
|
||||
use core::time::Duration;
|
||||
|
||||
/// An atomic for use as a futex that is at least 8-bits but may be larger.
|
||||
pub type SmallAtomic = AtomicU8;
|
||||
/// Must be the underlying type of SmallAtomic
|
||||
pub type SmallPrimitive = u8;
|
||||
|
||||
pub unsafe trait Waitable {
|
||||
type Atomic;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
use crate::sync::atomic::{
|
||||
self,
|
||||
Ordering::{Acquire, Relaxed, Release},
|
||||
};
|
||||
use crate::sys::futex::{futex_wait, futex_wake};
|
||||
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||
use crate::sys::futex::{self, futex_wait, futex_wake};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(windows)] {
|
||||
// On Windows we can have a smol futex
|
||||
type Atomic = atomic::AtomicU8;
|
||||
type State = u8;
|
||||
} else {
|
||||
type Atomic = atomic::AtomicU32;
|
||||
type State = u32;
|
||||
}
|
||||
}
|
||||
type Atomic = futex::SmallAtomic;
|
||||
type State = futex::SmallPrimitive;
|
||||
|
||||
pub struct Mutex {
|
||||
futex: Atomic,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
use crate::pin::Pin;
|
||||
use crate::sync::atomic::AtomicU32;
|
||||
use crate::sync::atomic::Ordering::{Acquire, Release};
|
||||
use crate::sys::futex::{futex_wait, futex_wake};
|
||||
use crate::sys::futex::{self, futex_wait, futex_wake};
|
||||
use crate::time::Duration;
|
||||
|
||||
const PARKED: u32 = u32::MAX;
|
||||
const EMPTY: u32 = 0;
|
||||
const NOTIFIED: u32 = 1;
|
||||
type Atomic = futex::SmallAtomic;
|
||||
type State = futex::SmallPrimitive;
|
||||
|
||||
const PARKED: State = State::MAX;
|
||||
const EMPTY: State = 0;
|
||||
const NOTIFIED: State = 1;
|
||||
|
||||
pub struct Parker {
|
||||
state: AtomicU32,
|
||||
state: Atomic,
|
||||
}
|
||||
|
||||
// Notes about memory ordering:
|
||||
|
|
@ -36,7 +39,7 @@ impl Parker {
|
|||
/// Construct the futex parker. The UNIX parker implementation
|
||||
/// requires this to happen in-place.
|
||||
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||
parker.write(Self { state: AtomicU32::new(EMPTY) });
|
||||
unsafe { parker.write(Self { state: Atomic::new(EMPTY) }) };
|
||||
}
|
||||
|
||||
// Assumes this is only called by the thread that owns the Parker,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(
|
||||
all(target_os = "windows", not(target_vendor = "win7")),
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
all(target_arch = "wasm32", target_feature = "atomics"),
|
||||
|
|
@ -18,9 +19,9 @@ cfg_if::cfg_if! {
|
|||
))] {
|
||||
mod id;
|
||||
pub use id::Parker;
|
||||
} else if #[cfg(target_os = "windows")] {
|
||||
mod windows;
|
||||
pub use windows::Parker;
|
||||
} else if #[cfg(target_vendor = "win7")] {
|
||||
mod windows7;
|
||||
pub use windows7::Parker;
|
||||
} else if #[cfg(all(target_vendor = "apple", not(miri)))] {
|
||||
mod darwin;
|
||||
pub use darwin::Parker;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue