Skip to main content

mnemosyne/
lib.rs

1//! The Mnemosyne high-performance memory allocator global interface.
2
3#![no_std]
4#![deny(missing_docs)]
5
6extern crate alloc;
7// `counting` keeps its per-thread counters in `std::thread_local!`.
8// `mnemosyne-local`, a required dependency, already links `std`, so this adds
9// no requirement.
10extern crate std;
11
12mod allocator;
13pub mod counting;
14mod options;
15pub mod scratch;
16mod stats;
17
18pub use allocator::{Mnemosyne, MnemosyneAllocator};
19pub use mnemosyne_arena::aligned_vec;
20pub use mnemosyne_backend::{
21    CudaDeviceBackend, CudaGddrBackend, CudaHbmBackend, CudaHostPinnedBackend, CudaUnifiedBackend,
22    MemoryBackendWrapper, is_cuda_available,
23};
24pub use mnemosyne_core::{
25    AllocPolicy, HardenedPolicy, PolicyMarker, SecurePolicy, StandardPolicy,
26    constants::NUM_SIZE_CLASSES,
27    mitigations,
28    options::MnemosyneOptions,
29    size_class::{
30        LEMIRE_DIV_SHIFT, SizeClassInfo, all_class_info, block_index_in_page, class_to_max_blocks,
31        class_to_size, round_up_size_saturating, size_class_fragmentation, size_to_class,
32        size_to_class_nonzero,
33    },
34};
35#[cfg(feature = "branded")]
36pub use mnemosyne_heap::{
37    BrandedBlock, BrandedBox, BrandedCell, BrandedVec, Heap, InvariantLifetime, ReallocError,
38    ReallocFailure, SyncRegionToken, ThreadLocalToken, scope as branded_scope, sync_scope,
39};
40pub use mnemosyne_local::{
41    BinSnapshot, FastPathCacheConfig, FastPathCacheManager, FastPathEfficiencyMetrics,
42    LocalAllocatorSelector, SizeClassCache, SizeClassOccupancy, all_bin_snapshots,
43    alloc_distribution, bin_snapshot, flush_tls_stats, hottest_class, reset_bin_stats,
44    reset_generation_count, summary_line, total_alloc_count, total_internal_fragmentation,
45    total_live_bytes, total_requested_bytes, usable_size,
46};
47pub use mnemosyne_prof::{
48    disable_leak_detector, disable_profiling, dump_leaks, dump_profile, enable_leak_detector,
49    enable_profiling, is_leak_detector_enabled, is_profiling_enabled, register_alloc_hook,
50    register_free_hook,
51};
52pub use options::{configure, get_options};
53pub use scratch::{
54    AlignedBuf, AlignedVec, DEFAULT_SCRATCH_ALIGN, Drain, IntoIter, MAX_POOL_SLOTS, ScratchBank,
55    ScratchElement, ScratchPool,
56};
57pub use stats::{
58    BinStatsWindow, MemoryStats, decay, memory_stats, memory_stats_generic, memory_stats_json,
59    policy_summary, purge, purge_generic, purge_lazy, purge_standard, reset, reset_generic,
60    top_n_classes,
61};
62
63/// Forces the Mnemosyne thread-local allocator to initialize for the current
64/// thread by performing a minimal allocation and deallocation through the
65/// `Mnemosyne` allocator.
66///
67/// Call this before starting any measurement window (e.g., a
68/// [`counting::measure`]) to flush thread-local-state initialization traffic
69/// — options parsing, arena segment acquisition, per-thread allocator setup —
70/// out of the window so that only the actual code under test is measured.
71///
72/// # Example
73///
74/// ```rust,no_run
75/// # use mnemosyne::warm_current_thread;
76/// warm_current_thread();
77/// // ... zero-allocation work; the warm call is outside the measure window
78/// ```
79pub fn warm_current_thread() {
80    use core::alloc::{GlobalAlloc, Layout};
81    let layout = Layout::new::<[u8; 8]>();
82    // SAFETY: `layout` is a valid non-zero `Layout` for eight bytes; the
83    // returned pointer is null-checked before deallocation.
84    let ptr = unsafe { Mnemosyne.alloc(layout) };
85    if !ptr.is_null() {
86        // SAFETY: `ptr` is a valid allocation from the `Mnemosyne` allocator
87        // with `layout`, and is freed exactly once immediately here.
88        unsafe { Mnemosyne.dealloc(ptr, layout) };
89    }
90}