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
97
98
99
100
//! [`Tcache`] -- per-thread, per-class magazine cache (Phase P2).
//!
//! A fixed array of per-class magazines, each an array of pointers (a
//! "magazine"/"stack"). Push/pop touch only the magazine array (hot,
//! sequential, cache-friendly); the block's own memory is not read until
//! the user uses it (no dependent load on the hit path).
//!
//! Owner-private: only the owning thread touches it. No atomics, no locks.
//! Cross-thread frees never touch it (they go to the per-segment ring).
use crateSMALL_CLASS_COUNT;
/// Bulk-mode bypass threshold (P7). When a class's consecutive-refill
/// streak reaches this value the magazine fast path is skipped for that
/// class — allocs go directly to `core.alloc` and frees to `core.dealloc`.
/// This avoids the per-free overflow flush cost on alloc-without-free
/// streaks (the bulk microbench pattern).
///
/// The streak counts consecutive magazine **misses** (refills), NOT
/// individual allocs. Each refill pulls `REFILL_N` (= `TCACHE_CAP` = 16)
/// blocks. So `BULK_THRESHOLD = 3` means 3 consecutive refills without an
/// intervening overflow (= 48 allocs). This keeps the magazine HIT path
/// (the churn hot path) completely streak-free — no read, no write.
///
/// Only the refill (miss) and dealloc overflow paths touch the streak,
/// and both are already slow paths.
pub const BULK_THRESHOLD: u8 = 3;
/// Bulk-mode re-entry hysteresis (P7). Documented design parameter;
/// currently unused in the implementation. In the current design,
/// bulk mode has no explicit exit: the streak stays high once set.
/// Under churn the magazine stays populated (alloc hits, dealloc
/// pushes), so the streak check (on miss or overflow) is never
/// reached — bulk mode is "dormant." If the workload shifts to
/// churn, the magazine path handles it without checking the streak.
pub const BULK_LOW_THRESHOLD: u8 = 0;
/// Magic constant for tcache-resident block marker (M2 double-free guard, P3).
///
/// Non-zero so an all-zero freshly-carved block does not collide. The actual
/// key written into a block's word1 is `TCACHE_KEY ^ (heap.id as usize)` so
/// different heaps have different keys (defence against confusion across
/// registry slots).
///
/// Value: ASCII bytes "SEFERCAC" packed into a `usize`. On 32-bit targets
/// only the low 4 bytes ("SEFE") are used, which is still non-zero and
/// distinctive.
pub const TCACHE_KEY: usize = 0x53_45_46_45_52_43_41_43;
/// Magazine capacity per size class. Start: 16. Tuned in P6.
pub const TCACHE_CAP: usize = 16;
/// Refill batch size (how many blocks refill_class pulls on a magazine miss).
pub const REFILL_N: usize = TCACHE_CAP;
/// Flush batch size on magazine overflow. Half-flush hysteresis: leave
/// `CAP - FLUSH_N` entries in the magazine after a flush, avoiding
/// flush/refill thrash when the working set hovers near CAP.
pub const FLUSH_N: usize = TCACHE_CAP / 2; // 8
/// Per-thread, per-class magazine cache.
///
/// `slots[c][0..count[c]]` are valid free-block pointers of class `c`.
/// The magazine is owner-private (single thread reads/writes it). No
/// atomics, no locks.
pub