#[cfg(target_os = "windows")]
mod windows {
use std::marker::PhantomData;
use std::sync::atomic::AtomicU32;
pub(crate) struct HrTimerLock {
pub(super) _unconstructable: PhantomData<()>,
}
impl Drop for HrTimerLock {
fn drop(&mut self) {
dec_ref();
}
}
static TIMER_REFCOUNT: AtomicU32 = AtomicU32::new(0);
pub(super) fn inc_ref() {
let old = TIMER_REFCOUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
debug_assert!(old != u32::MAX);
if old == 0 {
lock_hr();
}
}
fn dec_ref() {
let old = TIMER_REFCOUNT.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
debug_assert!(old != 0);
if old == 1 {
unlock_hr();
}
}
fn lock_hr() {
unsafe { windows_sys::Win32::Media::timeBeginPeriod(1) };
}
fn unlock_hr() {
unsafe { windows_sys::Win32::Media::timeEndPeriod(1) };
}
}
#[cfg(target_os = "windows")]
pub(crate) fn hr_timer_lock() -> windows::HrTimerLock {
windows::inc_ref();
windows::HrTimerLock {
_unconstructable: Default::default(),
}
}
#[cfg(not(target_os = "windows"))]
pub(crate) fn hr_timer_lock() -> (std::marker::PhantomData<()>,) {
(std::marker::PhantomData::default(),)
}