pub(crate) fn available() -> bool {
imp::available()
}
pub(crate) fn heavy() -> bool {
imp::heavy()
}
#[cfg(all(target_os = "linux", not(miri), not(all(loom, test))))]
mod imp {
use std::sync::OnceLock;
fn membarrier(cmd: libc::c_int) -> bool {
unsafe { libc::syscall(libc::SYS_membarrier, cmd, 0, 0) == 0 }
}
pub(super) fn available() -> bool {
static REGISTERED: OnceLock<bool> = OnceLock::new();
*REGISTERED.get_or_init(|| membarrier(libc::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED))
}
pub(super) fn heavy() -> bool {
membarrier(libc::MEMBARRIER_CMD_PRIVATE_EXPEDITED)
}
}
#[cfg(all(windows, not(miri), not(all(loom, test))))]
mod imp {
pub(super) fn available() -> bool {
true
}
pub(super) fn heavy() -> bool {
unsafe { crate::syscore::windows::FlushProcessWriteBuffers() };
true
}
}
#[cfg(any(not(any(target_os = "linux", windows)), miri, all(loom, test)))]
mod imp {
pub(super) fn available() -> bool {
false
}
pub(super) fn heavy() -> bool {
crate::sync::internal::fence(crate::sync::internal::Ordering::SeqCst);
true
}
}
#[cfg(all(test, not(loom)))]
mod tests {
#[test]
fn a_heavy_fence_where_there_is_one_succeeds() {
if super::available() {
assert!(super::heavy());
assert!(super::heavy(), "again");
}
}
}