use crate::{LocalAllocatorSlot, ThreadAllocator};
use core::sync::atomic::AtomicU32;
use mnemosyne_arena::HasSegmentPool;
pub trait TlsSlotAccess<B: HasSegmentPool>: 'static {
fn get_slot_standard<R>(f: impl FnOnce(&LocalAllocatorSlot<B>) -> R) -> R;
fn get_cached_cell<R>(f: impl FnOnce(&core::cell::Cell<*mut core::ffi::c_void>) -> R) -> R;
fn arm_thread_exit(slot: &LocalAllocatorSlot<B>);
fn get_os_tls_key() -> &'static AtomicU32;
#[cfg(nightly_tls_active)]
fn get_slot_nightly<R>(f: impl FnOnce(&LocalAllocatorSlot<B>) -> R) -> R;
#[cfg(nightly_tls_active)]
fn get_quick_allocator_ptr() -> *mut core::ffi::c_void;
#[cfg(nightly_tls_active)]
fn set_quick_allocator_ptr(ptr: *mut core::ffi::c_void);
#[inline(always)]
fn slot_access_armed<R>(f: impl FnOnce(&mut ThreadAllocator<B>) -> R) -> Option<R> {
Self::get_slot_standard(|slot| {
Self::arm_thread_exit(slot);
unsafe { LocalAllocatorSlot::<B>::with_allocator(slot.allocator_ptr(), f) }
})
}
#[inline(always)]
unsafe fn slot_access_unguarded<R>(f: impl FnOnce(&mut ThreadAllocator<B>) -> R) -> Option<R> {
Self::get_slot_standard(|slot| {
unsafe { LocalAllocatorSlot::<B>::with_allocator_unguarded(slot.allocator_ptr(), f) }
})
}
}
pub trait TlsProvider<B: HasSegmentPool>: 'static {
const IDENTIFIER: &'static str;
fn register_current_allocator_ptr(ptr: *mut core::ffi::c_void);
fn with_allocator<R>(f: impl FnOnce(&mut ThreadAllocator<B>) -> R) -> Option<R>;
unsafe fn with_allocator_unguarded<R>(
f: impl FnOnce(&mut ThreadAllocator<B>) -> R,
) -> Option<R>;
fn get_allocator_ptr() -> *mut core::ffi::c_void;
#[inline(always)]
fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
Self::get_allocator_ptr()
}
}