pub struct DebugCheckingAllocator<A>where
A: BStackAllocator<Error = Error>,{ /* private fields */ }Expand description
Debug-only allocator wrapper that validates allocations and deallocations.
Wraps any BStackAllocator with Error = io::Error. This wrapper’s
allocated handle type is DebugHandle, which preserves the inner
allocator’s handle while enabling conversion to BStackSlice. It also
maintains sets of allocated and freed regions to detect overlaps.
§Constraints
This wrapper works with any allocator whose Allocated handles can convert
to and from BStackSlice, which includes all allocators provided by this
library (crate::LinearBStackAllocator, crate::FirstFitBStackAllocator,
crate::GhostTreeBstackAllocator, crate::ManualAllocator).
§Panics
Panics if:
- A newly allocated region overlaps with an existing allocated region
- A reallocated region overlaps with an existing allocated region
- A region being freed overlaps with a previously freed region
These panics indicate bugs in the underlying allocator implementation or a double free in the calling code.
§Thread Safety
The internal tracking sets are protected by a Mutex for internal bookkeeping, but
allocation operations and tracking updates must not be assumed to be an atomic,
cross-thread synchronization boundary. Concurrent use of this debug wrapper is therefore
not supported unless the caller provides external synchronization.
Implementations§
Source§impl<A> DebugCheckingAllocator<A>where
A: BStackAllocator<Error = Error>,
impl<A> DebugCheckingAllocator<A>where
A: BStackAllocator<Error = Error>,
Sourcepub fn new(inner: A) -> Self
pub fn new(inner: A) -> Self
Create a new DebugCheckingAllocator wrapping inner.
The allocator starts with empty tracking sets. If you’re reopening
a file from a previous session and want to pre-populate those sets,
use Self::with_state instead.
Sourcepub fn with_state(
inner: A,
allocated: impl IntoIterator<Item = Range<u64>>,
freed: impl IntoIterator<Item = Range<u64>>,
) -> Self
pub fn with_state( inner: A, allocated: impl IntoIterator<Item = Range<u64>>, freed: impl IntoIterator<Item = Range<u64>>, ) -> Self
Create a new DebugCheckingAllocator wrapping inner, with pre-populated tracking sets.
Use this when reopening a file from a previous session and you have metadata to reconstruct which regions were allocated or freed.
§Panics
Panics if the initial state is inconsistent:
- Any two ranges within
allocatedoverlap - Any two ranges within
freedoverlap - Any range in
allocatedoverlaps with any range infreed
Sourcepub fn into_inner(self) -> A
pub fn into_inner(self) -> A
Consume this allocator and return the inner allocator.
Trait Implementations§
Source§impl<A> BStackAllocator for DebugCheckingAllocator<A>where
A: BStackAllocator<Error = Error>,
Method Atomic Notes
allocNo Inner alloc then tracking update are two separate steps
reallocNo Inner realloc then tracking swap are two separate steps
deallocNo Tracking validation then inner dealloc are two separate steps
impl<A> BStackAllocator for DebugCheckingAllocator<A>where
A: BStackAllocator<Error = Error>,
| Method | Atomic | Notes |
|---|---|---|
alloc | No | Inner alloc then tracking update are two separate steps |
realloc | No | Inner realloc then tracking swap are two separate steps |
dealloc | No | Tracking validation then inner dealloc are two separate steps |
A crash between the inner operation and the tracking update leaves the in-memory state inconsistent, but because tracking state is not persistent this only matters within a single process run.
Source§type Allocated<'a> = DebugHandle<'a, A>
where
A: 'a
type Allocated<'a> = DebugHandle<'a, A> where A: 'a
Source§fn into_stack(self) -> BStack ⓘ
fn into_stack(self) -> BStack ⓘ
Source§fn alloc(&self, len: u64) -> Result<Self::Allocated<'_>>
fn alloc(&self, len: u64) -> Result<Self::Allocated<'_>>
len zero-initialised bytes. Read moreSource§fn realloc<'a>(
&'a self,
handle: Self::Allocated<'a>,
new_len: u64,
) -> Result<Self::Allocated<'a>>
fn realloc<'a>( &'a self, handle: Self::Allocated<'a>, new_len: u64, ) -> Result<Self::Allocated<'a>>
Source§fn dealloc(&self, handle: Self::Allocated<'_>) -> Result<()>
fn dealloc(&self, handle: Self::Allocated<'_>) -> Result<()>
handle. Read more