MCPcopy Index your code
hub / github.com/Windfisch/rust-assert-no-alloc

github.com/Windfisch/rust-assert-no-alloc @v1.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.0.0 ↗ · + Follow
23 symbols 60 edges 3 files 5 documented · 22%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

assert_no_alloc

This crate provides a custom allocator that allows to temporarily disable memory (de)allocations for a thread. If a (de)allocation is attempted anyway, the program will abort or print a warning.

It uses thread local storage for the "disabled-flag/counter", and thus should be thread safe, if the underlying allocator (currently hard-coded to std::alloc::System) is.

Rationale

No-allocation-zones are relevant e.g. in real-time scenarios like audio callbacks. Allocation and deallocation can take unpredictable amounts of time, and thus can sometimes lead to audible glitches because the audio data is not served in time.

Debugging such problems can be hard, because it is difficult to reproduce such problems consistently. Avoiding such problems is also hard, since allocation/deallocation is a common thing to do and most libraries are not explicit whether certain functions can allocate or not. Also, this might even depend on the run-time situation (e.g. a Vec::push might allocate, but it is guaranteed to not allocate if enough space has been reserve()d before).

To aid the developer in tackling these problems, this crate offers an easy way of detecting all forbidden allocations.

How to use

First, configure the features: warn_debug and warn_release change the behaviour from aborting your program into just printing an error message on stderr. Aborting is useful for debugging purposes, as it allows you to retrieve a stacktrace, while warning is less intrusive.

Note that you need to disable the (default-enabled) disable_release feature by specify default-features = false if you want to use warn_release. If disable_release is set (which is the default), then this crate will do nothing if built in --release mode.

Second, use the allocator provided by this crate. Add this to main.rs:

use assert_no_alloc::*;

#[cfg(debug_assertions)] // required when disable_release is set (default)
#[global_allocator]
static A: AllocDisabler = AllocDisabler;

Third, wrap code sections that may not allocate like this:

assert_no_alloc(|| {
    println!("This code can not allocate.");
});

Advanced use

Values can be returned using:

let answer = assert_no_alloc(|| { 42 });

assert_no_alloc() calls can be nested, with proper panic unwinding handling.

Note that to fully bypass this crate, e.g. when in release mode, you need to both have the disable_release feature flag enabled (which it is by default) and to not register AllocDisabler as global_allocator.

Examples

See examples/main.rs for an example.

You can try out the different feature flags:

  • cargo run --example main -> memory allocation of 4 bytes failed. Aborted (core dumped)
  • cargo run --example main --release --no-default-features -> same as above.
  • cargo run --example main --features=warn_debug -> Tried to (de)allocate memory in a thread that forbids allocator calls! This will not be executed if the above allocation has aborted.
  • cargo run --example main --features=warn_release --release --no-default-features -> same as above.
  • cargo run --example main --release will not even check for forbidden allocations

Test suite

The tests will fail to compile with the default features. Run them using:

cargo test --features=warn_debug

Core symbols most depended-on inside this repo

assert_no_alloc
called by 18
src/lib.rs
violation_count
called by 3
src/lib.rs
check
called by 2
src/lib.rs
reset_violation_count
called by 1
src/lib.rs
fib
called by 1
examples/main.rs
new
called by 0
src/lib.rs
drop
called by 0
src/lib.rs
alloc
called by 0
src/lib.rs

Shape

Function 16
Method 5
Class 2

Languages

Rust100%

Modules by API surface

tests/test.rs11 symbols
src/lib.rs10 symbols
examples/main.rs2 symbols

For agents

$ claude mcp add rust-assert-no-alloc \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact