Workspace integration
Register crates/taktora-bounded-alloc in the root
Cargo.toml [workspace] members.
Crate has no runtime dependencies — only core and std
(the latter used only by the sample binary and integration
tests; lib.rs itself is #![no_std]-compatible).
``crates/taktora-bounded-alloc/Cargo.toml``
Inherits edition, rust-version, license, etc. from
workspace.
[profile.dev] and [profile.release] set panic =
"abort" (required by Lock-after-init panic mode (REQ_0302)).
[[example]] name = "fail_closed" for the sample binary.
``crates/taktora-bounded-alloc/src/lib.rs``
#![no_std] plus extern crate alloc only inside the
test cfg.
pub struct BoundedAllocator<const MAX_BLOCKS: usize,
const BLOCK_SIZE: usize> carrying arena, bitmap,
alloc_count, dealloc_count, peak_in_use,
locked.
pub const fn new() -> Self — usable in a static
initialiser.
unsafe impl GlobalAlloc providing alloc and dealloc.
alloc body — check locked (panic if true), check
layout.size() > BLOCK_SIZE (return null), bit-scan the
bitmap for a free word, compare_exchange to claim a bit,
bump counters, return pointer; dealloc body — derive
block index from pointer offset, set bit, bump
dealloc_count.
realloc falls through to the default GlobalAlloc impl
(alloc-new + copy_nonoverlapping + dealloc-old).
pub fn lock(&self), pub fn is_locked(&self) -> bool,
pub fn alloc_count(&self) -> usize,
pub fn dealloc_count(&self) -> usize,
pub fn peak_blocks_used(&self) -> usize.
Single #[allow(unsafe_code)] block for the arena pointer
arithmetic, with a // SAFETY: comment citing the
bitmap-CAS invariant (a thread that observes a 1->0
transition on bit i is the unique owner of block i
until it CASs the bit back to 1 in dealloc).
``crates/taktora-bounded-alloc/tests/``
``crates/taktora-bounded-alloc/examples/fail_closed.rs``
Sets a BoundedAllocator<8, 64> as #[global_allocator].
In main allocates Box<[u8; 32]> in a loop, printing
the running block index, until the 9th allocation triggers
the default alloc_error_handler → abort. The
surviving 8 allocations are observable in the printed output
before the abort; the process exits with a non-zero status
(SIGABRT). Demonstrates Fail-closed on cap overrun (REQ_0301) end-to-end.
``crates/taktora-executor/tests/no_alloc_dispatch.rs`` migration
Replace the inline CountingAllocator (the existing
~70 lines covering GlobalAlloc, size buckets, tracking
flag) with a dependency on taktora-bounded-alloc’s public
counting API. Set MAX_BLOCKS deliberately high
(~``1 << 20``) so the steady-state caps never fire during
the differential measurement — No heap allocation in dispatch (REQ_0060) is about
the count, not about provisioning.
Add taktora-bounded-alloc to
crates/taktora-executor/Cargo.toml [dev-dependencies].
Delete the size-bucket diagnostic and the
trip_first_alloc_backtrace test (use the new crate’s
counters; deeper triage stays a developer-side workflow,
not a checked-in test).
|