#[non_exhaustive]pub struct AllocStats {
pub total_allocations: CachePadded<AtomicUsize>,
pub total_deallocations: CachePadded<AtomicUsize>,
pub bytes_allocated: CachePadded<AtomicUsize>,
pub bytes_peak: CachePadded<AtomicUsize>,
pub failures: CachePadded<AtomicUsize>,
pub corruption_events: CachePadded<AtomicUsize>,
}Expand description
Snapshot of allocation activity. All counters are atomic; reading is
Ordering::Relaxed because counter values are advisory (operators read
them for diagnostics, not for ordering guarantees).
Each counter is wrapped in CachePadded so concurrent updates from
different code paths (alloc / dealloc / failure) don’t ping-pong as a
single cache line when Statistics wraps a multi-thread allocator
(e.g. Statistics<SharedBumpArena>). The public field type therefore
reads as CachePadded<AtomicUsize>; auto-deref keeps the call sites
(stats.total_allocations.fetch_add(...)) unchanged.
§Width: AtomicUsize, not AtomicU64
Each counter is AtomicUsize so this crate compiles on 32-bit
bare-metal targets (Cortex-M3/M4, thumbv7em-none-eabihf,
wasm32-unknown-unknown without the atomics feature) that lack
native 64-bit atomic ops. The convenience helpers (current_bytes,
peak_bytes, live_count) widen each load to u64 at the
boundary so the public read-API is uniform across host widths.
Practical impact on 32-bit:
bytes_allocated/bytes_peak: capped atusize::MAX(4 GiB on 32-bit), which equals the address-space ceiling anyway — a tighter cap is impossible on these targets.total_allocations/total_deallocations/failures: cap atu32::MAX ≈ 4.3 B. For long-running 32-bit deployments, the counter wraps after that many ops; values are advisory only.corruption_events: cap atu32::MAX. Even at one event per microsecond (already an unrealistic attack rate) the counter would not wrap for ~71 minutes; real workloads see ≪1 event/year.
Marked #[non_exhaustive] so additional observability counters can
be added in future releases without a breaking change.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.total_allocations: CachePadded<AtomicUsize>Total successful allocate calls observed by this wrapper.
total_deallocations: CachePadded<AtomicUsize>Total deallocate calls observed by this wrapper.
bytes_allocated: CachePadded<AtomicUsize>Bytes currently held by live allocations.
bytes_peak: CachePadded<AtomicUsize>High-water mark of bytes_allocated.
failures: CachePadded<AtomicUsize>Failed allocate calls (returned AllocError).
corruption_events: CachePadded<AtomicUsize>Detected freelist / metadata corruption events, mirrored from
the inner allocator’s Allocator::corruption_events counter
via fetch_max on each allocate/deallocate call through this
wrapper.
The inner allocator is the source of truth (each corruption-
detection site bumps its allocator-local counter at the moment
of detection); this mirror lets readers of AllocStats see the
corruption count alongside the other counters without needing to
reach through to the inner.
Eventually consistent: between calls to this wrapper, the inner counter may have advanced. The mirror is updated on every allocate and deallocate through this wrapper.
Implementations§
Source§impl AllocStats
impl AllocStats
Sourcepub fn current_bytes(&self) -> u64
pub fn current_bytes(&self) -> u64
Bytes currently in use. Widened to u64 at the boundary so
callers get a uniform read-API across 32-bit and 64-bit hosts;
the underlying counter is AtomicUsize (capped at usize::MAX).
Sourcepub fn peak_bytes(&self) -> u64
pub fn peak_bytes(&self) -> u64
Peak bytes ever in use during the wrapper’s lifetime. Widened to
u64 at the boundary — see current_bytes.
Sourcepub fn live_count(&self) -> i64
pub fn live_count(&self) -> i64
Net live allocation count (allocations − deallocations).