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::*;