wait_on_address 0.1.5

Cross-platform atomic wait and wake (aka futex) functionality.
Documentation
use std::{
    sync::atomic::{AtomicU32, AtomicU64},
    time::Duration,
};

use crate::private::AtomicWaitImpl;

impl AtomicWaitImpl for AtomicU32 {
    type AtomicInner = u32;

    fn wait_timeout(&self, value: Self::AtomicInner, timeout: Option<Duration>) {
        unsafe {
            if let Some(time) = timeout {
                libc::os_sync_wait_on_address_with_timeout(
                    self as *const _ as *mut _,
                    value as u64,
                    size_of::<Self>(),
                    libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
                    libc::CLOCK_MONOTONIC,
                    time.as_nanos().min(u64::MAX as u128) as u64,
                );
            } else {
                libc::os_sync_wait_on_address(
                    self as *const _ as *mut _,
                    value as u64,
                    size_of::<Self>(),
                    libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
                );
            }
        }
    }

    fn notify_all(&self) {
        unsafe {
            libc::os_sync_wake_by_address_all(
                self as *const _ as *mut _,
                size_of::<Self>(),
                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
            );
        };
    }

    fn notify_one(&self) {
        unsafe {
            libc::os_sync_wake_by_address_any(
                self as *const _ as *mut _,
                size_of::<Self>(),
                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
            );
        };
    }
}

impl AtomicWaitImpl for AtomicU64 {
    type AtomicInner = u64;

    fn wait_timeout(&self, value: Self::AtomicInner, timeout: Option<Duration>) {
        unsafe {
            if let Some(time) = timeout {
                libc::os_sync_wait_on_address_with_timeout(
                    self as *const _ as *mut _,
                    value,
                    size_of::<Self>(),
                    libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
                    libc::CLOCK_MONOTONIC,
                    time.as_nanos().min(u64::MAX as u128) as u64,
                );
            } else {
                libc::os_sync_wait_on_address(
                    self as *const _ as *mut _,
                    value,
                    size_of::<Self>(),
                    libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
                );
            }
        }
    }

    fn notify_all(&self) {
        unsafe {
            libc::os_sync_wake_by_address_all(
                self as *const _ as *mut _,
                size_of::<Self>(),
                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
            );
        };
    }

    fn notify_one(&self) {
        unsafe {
            libc::os_sync_wake_by_address_any(
                self as *const _ as *mut _,
                size_of::<Self>(),
                libc::OS_SYNC_WAKE_BY_ADDRESS_NONE,
            );
        };
    }
}