landauer-allocator 0.1.0

Landauer-on-Drop global allocator — counts bit erasures on every dealloc.
Documentation
  • Coverage
  • 100%
    4 out of 4 items documented0 out of 2 items with examples
  • Size
  • Source code size: 11.31 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.37 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 59s Average build duration of successful builds.
  • all releases: 59s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • kwailapt/aevum
    1 0 5
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • kwailapt

landauer-allocator

Landauer-on-Drop global allocator — counts bit erasures on every dealloc.

Part of the Aevum physics kernel.

Crates.io docs.rs Apache-2.0

What It Is

A Rust global allocator that intercepts every dealloc call and counts the bits erased, then exposes the cumulative total via a lock-free atomic counter.

From this count you can compute the Landauer dissipation cost — the minimum energy required to erase those bits, grounded in the second law of thermodynamics:

Λ = bits_erased × k_B × T × ln(2)

where k_B = 1.380649 × 10⁻²³ J/K (SI 2019 exact) and T is temperature in Kelvin.

Why Intercept dealloc?

In Rust, when a variable's lifetime ends the Drop trait fires and heap memory is returned to the allocator. This deallocation is physically the moment when bits are irreversibly erased — the exact event that Landauer's principle taxes.

By wrapping every dealloc, the allocator counts bit erasures automatically and continuously. No application code needs to opt in. No code path can bypass Λ accounting, because no code path bypasses Drop.

This answers the question: "How far is my program from the Landauer limit?"

Usage

use landauer_allocator::LandauerAllocator;

#[global_allocator]
static A: LandauerAllocator = LandauerAllocator;

fn main() {
    let before = landauer_allocator::bits_erased();

    let v: Vec<u8> = (0..1024).collect();
    drop(v);

    let after = landauer_allocator::bits_erased();
    let delta = after - before;

    let cost_joules = landauer_allocator::landauer_cost_joules(delta, 300.0);
    println!("bits erased: {delta}");
    println!("Λ = {cost_joules:.3e} joules  (at 300 K)");
}

API

Function Description
bits_erased() → u64 Cumulative bits erased since process start. O(1), lock-free. Monotonically non-decreasing.
landauer_cost_joules(bits, temp_k) → f64 Λ = bits × k_B × T × ln(2). Returns cost in joules.

Safety Contract

The crate uses #![deny(unsafe_code)] at the crate level. The single #[allow(unsafe_code)] block is isolated in an inner module and wraps exactly:

  1. One delegation to System.alloc(layout)
  2. One delegation to System.dealloc(ptr, layout) — preceded by one AtomicU64::fetch_add

There is no pointer arithmetic, no raw memory reads, no lifetime violations. Each unsafe block carries a justification comment.

Physics Constant

const K_B: f64 = 1.380_649e-23;  // Boltzmann constant (SI 2019 exact)

// Λ per bit at 300 K:  k_B × 300 × ln(2) ≈ 2.87 × 10⁻²¹ joules

License

Apache-2.0 — see LICENSE.