use core::{
ffi::c_void,
sync::atomic::{AtomicU32, Ordering::Relaxed},
};
#[link(name = "c++")]
extern "C" {
#[link_name = "_ZNSt3__123__libcpp_atomic_monitorEPVKv"]
fn __libcpp_atomic_monitor(ptr: *const c_void) -> i64;
#[link_name = "_ZNSt3__120__libcpp_atomic_waitEPVKvx"]
fn __libcpp_atomic_wait(ptr: *const c_void, monitor: i64);
#[link_name = "_ZNSt3__123__cxx_atomic_notify_oneEPVKv"]
fn __cxx_atomic_notify_one(ptr: *const c_void);
#[link_name = "_ZNSt3__123__cxx_atomic_notify_allEPVKv"]
fn __cxx_atomic_notify_all(ptr: *const c_void);
}
#[inline]
pub fn wait(a: &AtomicU32, expected: u32) {
let ptr: *const AtomicU32 = a;
let monitor = unsafe { __libcpp_atomic_monitor(ptr.cast()) };
if a.load(Relaxed) != expected {
return;
}
unsafe { __libcpp_atomic_wait(ptr.cast(), monitor) };
}
#[inline]
pub fn wake_one(ptr: *const AtomicU32) {
unsafe { __cxx_atomic_notify_one(ptr.cast()) };
}
#[inline]
pub fn wake_all(ptr: *const AtomicU32) {
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
}