Expand description
Thread-safe bump arena allocator (native only — uses std::sync::Mutex).
Thread-safe bump allocator implementing allocator-api2’s Allocator trait.
§Why not bumpalo?
[bumpalo::Bump] is !Send + !Sync — bump allocation is inherently
single-threaded because the bump pointer is a plain Cell<usize>. BEAM’s
tokio multi-threaded runtime sends Arc<Put> between worker threads via
channels, which requires Put: Send. If the BTreeMap inside Put uses
a !Send allocator, the entire Put becomes !Send and cannot cross
thread boundaries.
§Design
SyncBumpArena wraps a Mutex<SyncBumpInner> behind an Arc. The mutex
is only contended during allocation (construction of BTreeMap nodes).
Read-only access to the BTreeMap (lookups, iteration, serialization) does
not touch the allocator at all — the Allocator trait’s allocate and
deallocate methods are only called during insertion and drop.
The inner state holds a chunk list (Vec<Chunk>) and a cursor pointing
into the current chunk. When the current chunk is exhausted, a new chunk
is allocated from the global allocator (doubling in size, starting at
4 KiB). deallocate is a no-op — all memory is freed at once when the
last Arc reference drops.
§Performance
- Allocation:
Mutex::lock+ pointer bump. The lock is held for nanoseconds (just advancing a cursor). In practice, contention is rare because BTreeMap construction happens in a single actor’s context. - Drop: O(chunks) — free each chunk. O(1) relative to the number of entries in the BTreeMap. This is the primary win: std’s BTreeMap drop walks every node; ours just frees a few chunks.
- Clone:
Arc::clone— one atomic increment.
§Safety
The unsafe impl Allocator delegates to SyncBumpInner::allocate,
which returns valid, aligned memory from a chunk. The memory remains
valid until the Arc<SyncBumpInner> is dropped (i.e., until all clones
of the arena are gone). deallocate is a no-op, which is sound for bump
allocators.
Structs§
- Sync
Bump Arena - A thread-safe bump arena allocator implementing
allocator-api2’sAllocatortrait.