P2: TLS SLL Redesign - class_map default, tls_cached tracking, conditional header restore

This commit completes the P2 phase of the Tiny Pool TLS SLL redesign to fix the
Header/Next pointer conflict that was causing ~30% crash rates.

Changes:
- P2.1: Make class_map lookup the default (ENV: HAKMEM_TINY_NO_CLASS_MAP=1 for legacy)
- P2.2: Add meta->tls_cached field to track blocks cached in TLS SLL
- P2.3: Make Header restoration conditional in tiny_next_store() (default: skip)
- P2.4: Add invariant verification functions (active + tls_cached ≈ used)
- P0.4: Document new ENV variables in ENV_VARS.md

New ENV variables:
- HAKMEM_TINY_ACTIVE_TRACK=1: Enable active/tls_cached tracking (~1% overhead)
- HAKMEM_TINY_NO_CLASS_MAP=1: Disable class_map (legacy mode)
- HAKMEM_TINY_RESTORE_HEADER=1: Force header restoration (legacy mode)
- HAKMEM_TINY_INVARIANT_CHECK=1: Enable invariant verification (debug)
- HAKMEM_TINY_INVARIANT_DUMP=1: Enable periodic state dumps (debug)

Benchmark results (bench_tiny_hot_hakmem 64B):
- Default (class_map ON): 84.49 M ops/sec
- ACTIVE_TRACK=1: 83.62 M ops/sec (-1%)
- NO_CLASS_MAP=1 (legacy): 85.06 M ops/sec
- MT performance: +21-28% vs system allocator

No crashes observed. All tests passed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-11-28 14:11:37 +09:00
parent 6b86c60a20
commit a6e681aae7
8 changed files with 154 additions and 17 deletions

View File

@ -37,8 +37,9 @@
#include <stdio.h>
#include <stdatomic.h>
// P1.3: Helper to increment meta->active when allocating from TLS SLL
// P1.3/P2.2: Helper to track active/tls_cached when allocating from TLS SLL
// ENV gate: HAKMEM_TINY_ACTIVE_TRACK=1 to enable (default: 0 for performance)
// Flow: TLS SLL → User means active++, tls_cached--
static inline void tiny_active_track_alloc(void* base) {
static __thread int g_active_track = -1;
if (__builtin_expect(g_active_track == -1, 0)) {
@ -53,6 +54,7 @@ static inline void tiny_active_track_alloc(void* base) {
if (slab_idx >= 0 && slab_idx < ss_slabs_capacity(ss)) {
TinySlabMeta* meta = &ss->slabs[slab_idx];
atomic_fetch_add_explicit(&meta->active, 1, memory_order_relaxed);
atomic_fetch_sub_explicit(&meta->tls_cached, 1, memory_order_relaxed); // P2.2
}
}
}