#[cfg(all(windows, not(miri)))]
mod windows;
#[cfg(all(windows, not(miri)))]
use windows as sys;
#[cfg(all(unix, not(miri)))]
mod unix;
#[cfg(all(unix, not(miri)))]
use unix as sys;
#[cfg(all(target_arch = "wasm32", not(miri)))]
mod wasm;
#[cfg(all(target_arch = "wasm32", not(miri)))]
use wasm as sys;
#[cfg(miri)]
pub mod mock;
#[cfg(miri)]
use mock as sys;
use core::ffi::c_void;
pub type PrimError = u32;
#[derive(Debug, Clone, Copy)]
pub struct MemConfig {
pub page_size: usize,
pub alloc_granularity: usize,
pub large_page_size: usize,
pub has_overcommit: bool,
pub has_partial_free: bool,
}
#[derive(Debug, Clone, Copy)]
pub struct Alloc {
pub ptr: *mut u8,
pub is_large: bool,
pub is_zero: bool,
}
pub fn mem_init() -> MemConfig {
sys::mem_init()
}
pub unsafe fn alloc(
size: usize,
try_alignment: usize,
commit: bool,
allow_large: bool,
) -> Result<Alloc, PrimError> {
unsafe { sys::alloc(size, try_alignment, commit, allow_large) }
}
pub unsafe fn free(ptr: *mut u8, size: usize) -> Result<(), PrimError> {
unsafe { sys::free(ptr, size) }
}
pub unsafe fn commit(ptr: *mut u8, size: usize) -> Result<bool, PrimError> {
unsafe { sys::commit(ptr, size) }
}
pub unsafe fn decommit(ptr: *mut u8, size: usize) -> Result<bool, PrimError> {
unsafe { sys::decommit(ptr, size) }
}
pub unsafe fn reset(ptr: *mut u8, size: usize) -> Result<(), PrimError> {
unsafe { sys::reset(ptr, size) }
}
pub unsafe fn protect(ptr: *mut u8, size: usize, protect: bool) -> Result<(), PrimError> {
unsafe { sys::protect(ptr, size, protect) }
}
pub fn numa_node_count() -> usize {
sys::numa_node_count().max(1)
}
#[inline]
pub fn thread_id() -> usize {
sys::thread_id()
}
pub fn clock_now() -> u64 {
sys::clock_now()
}
#[cfg(all(windows, not(miri)))]
pub type TlsDtor = unsafe extern "system" fn(*const c_void);
#[cfg(any(not(windows), miri))]
pub type TlsDtor = unsafe extern "C" fn(*mut c_void);
pub struct TlsSlot(sys::TlsSlotImpl);
impl TlsSlot {
pub fn new(dtor: Option<TlsDtor>) -> Option<TlsSlot> {
sys::tls_new(dtor).map(TlsSlot)
}
#[inline]
pub fn get(&self) -> *mut c_void {
sys::tls_get(&self.0)
}
#[inline]
pub fn set(&self, value: *mut c_void) {
sys::tls_set(&self.0, value)
}
pub fn into_raw(self) -> usize {
sys::tls_raw(&self.0)
}
pub unsafe fn from_raw(raw: usize) -> TlsSlot {
TlsSlot(sys::tls_from_raw(raw))
}
}
unsafe impl Send for TlsSlot {}
unsafe impl Sync for TlsSlot {}
#[inline]
pub(crate) const fn align_up(n: usize, align: usize) -> usize {
debug_assert!(align.is_power_of_two());
(n + align - 1) & !(align - 1)
}