Skip to main content

allocate/
talc.rs

1//! Talc allocator integration.
2//!
3//! `TalcAlloc` is a **type alias** for `&'static CacheTalcLock`. Talc's
4//! `Talck` already implements `allocator_api2::alloc::Allocator`, and
5//! `&'static T` inherits that impl. The whole "allocator handle" is
6//! just a borrow — `Copy + Clone + Send + Sync` for free.
7//!
8//! Construction is one line at the call site:
9//!
10//! - **Tests**: `&TALC` where
11//!   `static TALC: CacheTalcLock = new_cache_talc_lock();` (see the
12//!   `test_arena` helper).
13//! - **Production**: the talc lives at a fixed VA (mmap'd, pinned for
14//!   the process lifetime):
15//!   ```ignore
16//!   let alloc: TalcAlloc =
17//!       unsafe { &*(STATE_CACHE_VA as *const CacheTalcLock) };
18//!   ```
19//!   The single `unsafe { &*VA }` cast asserts the `'static` lifetime
20//!   that the mmap pinning guarantees.
21
22pub use lock_api::{Mutex, MutexGuard};
23pub use spinning_top::RawSpinlock;
24pub use talc::{ClaimOnOom, ErrOnOom, OomHandler, Span, Talc, Talck};
25
26/// Concrete `Talck` flavour used by the shared state-cache region.
27///
28/// `spinning_top::RawSpinlock` for serialisation (no `lock_api` direct
29/// dep needed downstream); `ErrOnOom` so OOM returns `Err` rather than
30/// attempting heap extension — callers hand talc its backing memory up
31/// front via `Talc::claim`.
32pub type CacheTalcLock = Talck<spinning_top::RawSpinlock, ErrOnOom>;
33
34/// Workspace allocator handle. Just a `'static` borrow of a
35/// [`CacheTalcLock`] — `Copy + Clone + Send + Sync` by reference, and
36/// the underlying `Talck` already impls
37/// `allocator_api2::alloc::Allocator`.
38pub type TalcAlloc = &'static CacheTalcLock;
39
40/// Const constructor for a fresh empty [`CacheTalcLock`]. Suitable for
41/// a `static` binding; backing memory must be supplied at runtime via
42/// `lock.lock().claim(Span::from_array(...))`.
43#[inline]
44pub const fn new_cache_talc_lock() -> CacheTalcLock {
45    Talc::new(ErrOnOom).lock()
46}