use super::traits::{TlsProvider, TlsSlotAccess};
use crate::ThreadAllocator;
#[cfg(nightly_tls_active)]
use crate::tls_slot::LocalAllocatorSlot;
use mnemosyne_arena::HasSegmentPool;
pub struct NightlyTls<B, S>(core::marker::PhantomData<(B, S)>);
impl<B: HasSegmentPool, S: TlsSlotAccess<B>> TlsProvider<B> for NightlyTls<B, S> {
const IDENTIFIER: &'static str = "NightlyTls";
#[inline(always)]
fn register_current_allocator_ptr(ptr: *mut core::ffi::c_void) {
#[cfg(nightly_tls_active)]
{
S::set_quick_allocator_ptr(ptr);
}
#[cfg(not(nightly_tls_active))]
{
let _ = ptr;
}
}
#[inline(always)]
fn with_allocator<R>(f: impl FnOnce(&mut ThreadAllocator<B>) -> R) -> Option<R> {
#[cfg(nightly_tls_active)]
{
S::get_slot_nightly(|slot| {
S::arm_thread_exit(slot);
unsafe { LocalAllocatorSlot::<B>::with_allocator(slot.allocator_ptr(), f) }
})
}
#[cfg(not(nightly_tls_active))]
{
let _ = f;
None
}
}
#[inline(always)]
unsafe fn with_allocator_unguarded<R>(
f: impl FnOnce(&mut ThreadAllocator<B>) -> R,
) -> Option<R> {
#[cfg(nightly_tls_active)]
{
S::get_slot_nightly(|slot| {
unsafe {
LocalAllocatorSlot::<B>::with_allocator_unguarded(slot.allocator_ptr(), f)
}
})
}
#[cfg(not(nightly_tls_active))]
{
let _ = f;
None
}
}
#[inline(always)]
fn get_allocator_ptr() -> *mut core::ffi::c_void {
#[cfg(nightly_tls_active)]
{
let ptr = S::get_quick_allocator_ptr();
if !ptr.is_null() {
ptr
} else {
S::get_slot_nightly(|slot| {
S::arm_thread_exit(slot);
let alloc_ptr = slot.allocator_ptr();
S::set_quick_allocator_ptr(alloc_ptr);
alloc_ptr
})
}
}
#[cfg(not(nightly_tls_active))]
{
core::ptr::null_mut()
}
}
#[inline(always)]
fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
#[cfg(nightly_tls_active)]
{
S::get_quick_allocator_ptr()
}
#[cfg(not(nightly_tls_active))]
{
core::ptr::null_mut()
}
}
}