bump_scope/
chunk_header.rs

1use core::{cell::Cell, ptr::NonNull};
2
3use crate::polyfill::non_null;
4
5/// The chunk header that lives at
6/// - the start of the allocation when upwards bumping
7/// - the end of the allocation when downwards bumping
8///
9/// All non-`Cell` fields are immutable.
10#[repr(C, align(16))]
11pub(crate) struct ChunkHeader<A = ()> {
12    pub(crate) pos: Cell<NonNull<u8>>,
13    pub(crate) end: NonNull<u8>,
14
15    pub(crate) prev: Cell<Option<NonNull<Self>>>,
16    pub(crate) next: Cell<Option<NonNull<Self>>>,
17
18    pub(crate) allocator: A,
19}
20
21/// Wraps a [`ChunkHeader`], making it Sync so it can be used as a static.
22/// The empty chunk is never mutated, so this is fine.
23struct UnallocatedChunkHeader(ChunkHeader);
24
25unsafe impl Sync for UnallocatedChunkHeader {}
26
27static UNALLOCATED_CHUNK_HEADER: UnallocatedChunkHeader = UnallocatedChunkHeader(ChunkHeader {
28    pos: Cell::new(NonNull::<UnallocatedChunkHeader>::dangling().cast()),
29    end: NonNull::<UnallocatedChunkHeader>::dangling().cast(),
30    prev: Cell::new(None),
31    next: Cell::new(None),
32    allocator: (),
33});
34
35impl ChunkHeader {
36    pub(crate) const UNALLOCATED: NonNull<ChunkHeader> = non_null::from_ref(&UNALLOCATED_CHUNK_HEADER.0);
37}