Skip to main content

fail_closed/
fail_closed.rs

1//! Sample binary demonstrating fail-closed-on-cap behaviour
2//! (REQ_0301). Registers a `BoundedAllocator<MAX_BLOCKS, 4096>` as
3//! `#[global_allocator]`. The arena is sized so that:
4//!
5//! * Rust runtime + stdlib startup fits inside the first few
6//!   blocks (Rust's stdlib allocates a few hundred bytes before
7//!   `main` runs).
8//! * The demo loop then `Box::new`s steadily-growing allocations
9//!   until the cap is hit; the over-cap allocation returns null,
10//!   Rust's default `alloc_error_handler` aborts the process.
11//!
12//! Run with:
13//!
14//! ```sh
15//! cargo run -p taktora-bounded-alloc --example fail_closed
16//! echo $?   # expect 134 (SIGABRT) or similar non-zero
17//! ```
18//!
19//! Expected output: a handful of "iter N: allocated; …" lines
20//! showing live block count climbing toward `MAX_BLOCKS`, then
21//! `memory allocation of N bytes failed` followed by abort.
22
23#![allow(missing_docs)]
24#![allow(clippy::doc_markdown)]
25
26use taktora_bounded_alloc::declare_global_allocator;
27
28const MAX_BLOCKS: usize = 16;
29const BLOCK_SIZE: usize = 4096;
30
31declare_global_allocator!(ALLOC, MAX_BLOCKS, BLOCK_SIZE);
32
33fn main() {
34    println!("taktora-bounded-alloc fail_closed demo");
35    println!("arena: {MAX_BLOCKS} blocks × {BLOCK_SIZE} bytes");
36    println!(
37        "blocks already in use after Rust runtime startup: {}",
38        ALLOC.live_blocks()
39    );
40    println!();
41
42    let mut held: Vec<Box<[u8; 1024]>> = Vec::new();
43    for i in 0_u32..64 {
44        let b: Box<[u8; 1024]> = Box::new([(i & 0xff) as u8; 1024]);
45        held.push(b);
46        println!(
47            "iter {i}: alloc_count={}, live={}, peak={}, held={}",
48            ALLOC.alloc_count(),
49            ALLOC.live_blocks(),
50            ALLOC.peak_blocks_used(),
51            held.len()
52        );
53    }
54
55    // Unreachable: an allocation past the cap returns null, and
56    // Rust's default alloc_error_handler aborts the process.
57    println!("unexpectedly reached end of main (cap was not exhausted)");
58}