Skip to content

Commit

Permalink
Auto merge of rust-lang#121317 - ChrisDenton:win10-sync, r=Mark-Simul…
Browse files Browse the repository at this point in the history
…acrum

Always use WaitOnAddress on Win10+

`WaitOnAddress` and `WakeByAddressSingle` are always available since Windows 8 so they can now be used without needing to delay load. I've also moved the Windows 7 thread parking fallbacks into a separate sub-module.
  • Loading branch information
bors committed Feb 26, 2024
2 parents 0250ef2 + 35421c7 commit dc00e8c
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 108 deletions.
28 changes: 21 additions & 7 deletions library/std/src/sys/pal/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,14 @@ pub type SIZE_T = usize;
pub type WORD = u16;
pub type CHAR = c_char;
pub type ULONG = c_ulong;
pub type ACCESS_MASK = DWORD;

pub type LPCVOID = *const c_void;
pub type LPHANDLE = *mut HANDLE;
pub type LPOVERLAPPED = *mut OVERLAPPED;
pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
pub type LPVOID = *mut c_void;
pub type LPWCH = *mut WCHAR;
pub type LPWSTR = *mut WCHAR;

pub type PLARGE_INTEGER = *mut c_longlong;
pub type PSRWLOCK = *mut SRWLOCK;

pub type socklen_t = c_int;
Expand Down Expand Up @@ -360,6 +357,19 @@ compat_fn_with_fallback! {
}
}

#[cfg(not(target_vendor = "win7"))]
#[link(name = "synchronization")]
extern "system" {
pub fn WaitOnAddress(
address: *const c_void,
compareaddress: *const c_void,
addresssize: usize,
dwmilliseconds: u32,
) -> BOOL;
pub fn WakeByAddressSingle(address: *const c_void);
}

#[cfg(target_vendor = "win7")]
compat_fn_optional! {
crate::sys::compat::load_synch_functions();
pub fn WaitOnAddress(
Expand All @@ -371,30 +381,34 @@ compat_fn_optional! {
pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void);
}

#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
compat_fn_with_fallback! {
pub static NTDLL: &CStr = c"ntdll";

#[cfg(target_vendor = "win7")]
pub fn NtCreateKeyedEvent(
KeyedEventHandle: LPHANDLE,
DesiredAccess: ACCESS_MASK,
KeyedEventHandle: *mut HANDLE,
DesiredAccess: DWORD,
ObjectAttributes: LPVOID,
Flags: ULONG
) -> NTSTATUS {
panic!("keyed events not available")
}
#[cfg(target_vendor = "win7")]
pub fn NtReleaseKeyedEvent(
EventHandle: HANDLE,
Key: LPVOID,
Alertable: BOOLEAN,
Timeout: PLARGE_INTEGER
Timeout: *mut c_longlong
) -> NTSTATUS {
panic!("keyed events not available")
}
#[cfg(target_vendor = "win7")]
pub fn NtWaitForKeyedEvent(
EventHandle: HANDLE,
Key: LPVOID,
Alertable: BOOLEAN,
Timeout: PLARGE_INTEGER
Timeout: *mut c_longlong
) -> NTSTATUS {
panic!("keyed events not available")
}
Expand Down
11 changes: 10 additions & 1 deletion library/std/src/sys/pal/windows/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

use crate::ffi::{c_void, CStr};
use crate::ptr::NonNull;
use crate::sync::atomic::Ordering;
use crate::sys::c;

// This uses a static initializer to preload some imported functions.
Expand All @@ -38,6 +37,7 @@ use crate::sys::c;
// file an issue for discussion; currently we don't guarantee any functionality
// before main.
// See https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
#[cfg(target_vendor = "win7")]
#[used]
#[link_section = ".CRT$XCT"]
static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
Expand All @@ -52,6 +52,7 @@ static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
/// negative performance impact in practical situations.
///
/// Currently we only preload `WaitOnAddress` and `WakeByAddressSingle`.
#[cfg(target_vendor = "win7")]
unsafe extern "C" fn init() {
// In an exe this code is executed before main() so is single threaded.
// In a DLL the system's loader lock will be held thereby synchronizing
Expand Down Expand Up @@ -183,6 +184,7 @@ macro_rules! compat_fn_with_fallback {
func($($argname),*)
}
}
#[allow(unused)]
$(#[$meta])*
$vis use $symbol::call as $symbol;
)*)
Expand All @@ -191,6 +193,7 @@ macro_rules! compat_fn_with_fallback {
/// Optionally loaded functions.
///
/// Actual loading of the function defers to $load_functions.
#[cfg(target_vendor = "win7")]
macro_rules! compat_fn_optional {
($load_functions:expr;
$(
Expand Down Expand Up @@ -218,13 +221,19 @@ macro_rules! compat_fn_optional {
NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
}
}
#[inline]
pub unsafe extern "system" fn $symbol($($argname: $argtype),*) $(-> $rettype)? {
$symbol::option().unwrap()($($argname),*)
}
)+
)
}

/// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
#[cfg(target_vendor = "win7")]
pub(super) fn load_synch_functions() {
fn try_load() -> Option<()> {
use crate::sync::atomic::Ordering;
const MODULE_NAME: &CStr = c"api-ms-win-core-synch-l1-2-0";
const WAIT_ON_ADDRESS: &CStr = c"WaitOnAddress";
const WAKE_BY_ADDRESS_SINGLE: &CStr = c"WakeByAddressSingle";
Expand Down
Loading

0 comments on commit dc00e8c

Please sign in to comment.