use core::{cell::Cell, ptr::NonNull};
use crate::{polyfill::non_null, settings::BumpAllocatorSettings};
#[repr(C, align(16))]
pub(crate) struct ChunkHeader<A = ()> {
pub(crate) pos: Cell<NonNull<u8>>,
pub(crate) end: NonNull<u8>,
pub(crate) prev: Cell<Option<NonNull<Self>>>,
pub(crate) next: Cell<Option<NonNull<Self>>>,
pub(crate) allocator: A,
}
struct DummyChunkHeader(ChunkHeader);
unsafe impl Sync for DummyChunkHeader {}
macro_rules! dummy_chunk {
($name:ident) => {
pub(crate) const fn $name<S: BumpAllocatorSettings>() -> NonNull<ChunkHeader> {
static UP_CHUNK: DummyChunkHeader = DummyChunkHeader(ChunkHeader {
pos: Cell::new(unsafe { UP_CHUNK_PTR.cast().byte_add(16) }),
end: UP_CHUNK_PTR.cast(),
prev: Cell::new(None),
next: Cell::new(None),
allocator: (),
});
static DOWN_CHUNK: DummyChunkHeader = DummyChunkHeader(ChunkHeader {
pos: Cell::new(DOWN_CHUNK_PTR.cast()),
end: unsafe { DOWN_CHUNK_PTR.cast().byte_add(16) },
prev: Cell::new(None),
next: Cell::new(None),
allocator: (),
});
const UP_CHUNK_PTR: NonNull<ChunkHeader> = non_null::from_ref(&UP_CHUNK.0);
const DOWN_CHUNK_PTR: NonNull<ChunkHeader> = non_null::from_ref(&DOWN_CHUNK.0);
if S::UP { UP_CHUNK_PTR } else { DOWN_CHUNK_PTR }
}
};
}
impl ChunkHeader {
dummy_chunk!(unallocated);
dummy_chunk!(claimed);
}