1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! The public free entry points.
use thread_free_classified;
use crateLocalAllocatorSelector;
use HasSegmentPool;
use AllocPolicy;
/// Frees a memory block.
///
/// # Safety
///
/// The ptr must be valid and must have been returned by a previous allocation.
/// A null pointer is ignored, matching `free(NULL)`.
///
/// # Examples
///
/// ```
/// use mnemosyne_local::{thread_alloc, thread_free};
/// use mnemosyne_core::StandardPolicy;
/// use mnemosyne_backend::MemoryBackendWrapper as Backend;
///
/// // SAFETY: `p` comes from `thread_alloc` and is freed exactly once. Freeing
/// // it twice, or freeing a pointer this allocator did not return, is
/// // undefined behaviour that the allocator aborts on when it detects it.
/// unsafe {
/// let p = thread_alloc::<StandardPolicy, Backend>(32, 8);
/// assert!(!p.is_null());
/// thread_free::<StandardPolicy, Backend>(p);
///
/// // Freeing null is a no-op, so callers need no guard of their own.
/// thread_free::<StandardPolicy, Backend>(core::ptr::null_mut());
/// }
/// ```
pub unsafe
/// Frees a memory block when the caller has a valid Rust `Layout`.
///
/// The layout-proven small path monomorphizes out the large/huge classifier
/// branch while retaining the raw `thread_free` fallback for large, huge, or
/// unusual-alignment allocations.
///
/// # Safety
///
/// Same contract as [`thread_free`], and `size`/`align` must come from the
/// original allocation layout.
/// # Examples
///
/// ```
/// use core::alloc::Layout;
/// use mnemosyne_local::{thread_alloc_layout, thread_free_layout};
/// use mnemosyne_core::StandardPolicy;
/// use mnemosyne_backend::MemoryBackendWrapper as Backend;
///
/// let layout = Layout::from_size_align(96, 16).expect("96/16 is a valid layout");
///
/// // SAFETY: the `size`/`align` passed to the free are the ones the
/// // allocation was made with; a mismatched layout would misroute the free.
/// unsafe {
/// let p = thread_alloc_layout::<StandardPolicy, Backend>(layout.size(), layout.align());
/// assert!(!p.is_null());
/// thread_free_layout::<StandardPolicy, Backend>(p, layout.size(), layout.align());
/// }
/// ```
pub unsafe