Skip to main content

memory/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Cédric Mesnil <cslashm@pm.me>
3
4//! Shared memory allocator for the krypteia cryptographic workspace.
5//!
6//! This crate provides the workspace allocator — a TLSF heap over a
7//! caller-provided RAM block, or a thin shim over the platform
8//! `malloc`/`free`. On targets without an OS heap it is registered as
9//! the `#[global_allocator]` (via the `global-alloc` feature) by
10//! `arcana_ffi` and `tessera_ffi`. `quantica_ffi` does not depend on
11//! this crate — the post-quantum FFI performs no heap allocation of
12//! its own.
13//!
14//! # Feature flags
15//!
16//! | Feature        | Behaviour                                                          |
17//! |----------------|--------------------------------------------------------------------|
18//! | `os-alloc`     | The platform provides `malloc`/`free`. Init is a no-op. Default.    |
19//! | `self-alloc`   | TLSF allocator over a caller-provided RAM block (`no_std`).         |
20//! | `global-alloc` | Implies `self-alloc` and registers it as `#[global_allocator]` for the FFI crates. |
21//!
22//! Enable **exactly one** allocator backend. `os-alloc` (the default)
23//! and `self-alloc` are mutually exclusive (enforced by a
24//! `compile_error!` below); `global-alloc` is a superset of
25//! `self-alloc`.
26//!
27//! # Usage from C (bare-metal)
28//!
29//! ```c
30//! #include "krypteia.h"
31//!
32//! static uint8_t heap[8192];
33//!
34//! int main(void) {
35//!     krypteia_init(heap, sizeof(heap));
36//!     // … use arcana or quantica APIs …
37//! }
38//! ```
39
40#![cfg_attr(feature = "self-alloc", no_std)]
41
42#[cfg(all(feature = "self-alloc", feature = "os-alloc"))]
43compile_error!("features `os-alloc` and `self-alloc` are mutually exclusive");
44
45// ====================================================================
46// os-alloc: the platform already has malloc/free — nothing to do
47// ====================================================================
48
49#[cfg(feature = "os-alloc")]
50mod os_alloc {
51    /// Memory allocation statistics.
52    #[derive(Clone, Copy, Debug, Default)]
53    pub struct MemStats {
54        /// Bytes currently allocated.
55        pub used: usize,
56        /// Bytes still available.
57        pub free: usize,
58        /// High-water mark since init.
59        pub peak: usize,
60    }
61
62    /// No-op initialiser for `os-alloc` mode (the platform heap needs no
63    /// setup).
64    ///
65    /// # Parameters
66    /// - `_base`: ignored (the OS owns the heap region).
67    /// - `_size`: ignored.
68    ///
69    /// # Returns
70    /// Always `0` (success), matching the `self-alloc` `krypteia_init`
71    /// contract (`0` = ok, `-1` = failure) so FFI callers can treat both
72    /// backends identically.
73    ///
74    /// # Safety
75    ///
76    /// Always safe; arguments are ignored.
77    pub unsafe fn krypteia_init(_base: *mut u8, _size: usize) -> i32 {
78        0
79    }
80
81    /// Returns zeroed stats in `os-alloc` mode (the OS tracks its
82    /// own heap; we have no visibility).
83    pub fn memory_stats() -> MemStats {
84        MemStats::default()
85    }
86}
87
88#[cfg(feature = "os-alloc")]
89pub use os_alloc::*;
90
91// ====================================================================
92// self-alloc: TLSF allocator over a caller-provided RAM block
93// ====================================================================
94
95#[cfg(feature = "self-alloc")]
96mod self_alloc;
97
98#[cfg(feature = "self-alloc")]
99pub use self_alloc::*;