Phase POOL-FREE-V1-OPT Step 1: Add v2 reject stats tracking

Add reject reason counters for v2 free path to understand fallback patterns:
- v2_reject_total: Total v2 free rejects
- v2_reject_ptr_null: ptr == NULL
- v2_reject_not_init: pool not initialized
- v2_reject_desc_null: mid_desc_lookup returned NULL
- v2_reject_mf2_null: MF2 path but mf2_addr_to_page returned NULL

ENV gate: HAKMEM_POOL_FREE_V1_REJECT_STATS (default OFF)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-12 19:43:03 +09:00
parent fe70e3baf5
commit dbdd2e0e0e

View File

@ -64,6 +64,17 @@ static inline int hak_pool_v1_flatten_stats_enabled(void) {
return g;
}
// Phase POOL-FREE-V1-OPT Step 1: Reject reason stats
// Tracks why hak_pool_free_fast_v2_impl rejected (fell through to v1)
static inline int hak_pool_free_v1_reject_stats_enabled(void) {
static int g = -1;
if (__builtin_expect(g == -1, 0)) {
const char* e = getenv("HAKMEM_POOL_FREE_V1_REJECT_STATS");
g = (e && *e == '1') ? 1 : 0; // default OFF
}
return g;
}
// Mid desc lookup TLS cache (mid bench opt-in; default OFF)
static inline int hak_mid_desc_cache_enabled(void) {
static int g = -1;
@ -104,28 +115,52 @@ typedef struct PoolV1FlattenStats {
_Atomic uint64_t free_fb_page_null;
_Atomic uint64_t free_fb_not_mine;
_Atomic uint64_t free_fb_other;
// Phase POOL-FREE-V1-OPT Step 1: v2 reject reasons
_Atomic uint64_t v2_reject_total; // Total v2 free rejects (fell through to v1)
_Atomic uint64_t v2_reject_ptr_null; // ptr == NULL
_Atomic uint64_t v2_reject_not_init; // pool not initialized
_Atomic uint64_t v2_reject_desc_null; // mid_desc_lookup returned NULL
_Atomic uint64_t v2_reject_mf2_null; // MF2 path but mf2_addr_to_page returned NULL
} PoolV1FlattenStats;
static PoolV1FlattenStats g_pool_v1_flat_stats = {0};
static inline void pool_v1_flat_stats_dump(void) {
if (!hak_pool_v1_flatten_stats_enabled()) return;
fprintf(stderr,
"[POOL_V1_FLAT] alloc_tls_hit=%llu alloc_fb=%llu free_tls_hit=%llu free_fb=%llu page_null=%llu not_mine=%llu other=%llu\n",
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.alloc_tls_hit,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.alloc_fallback_v1,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_tls_hit,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fallback_v1,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_page_null,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_not_mine,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_other,
memory_order_relaxed));
if (!hak_pool_v1_flatten_stats_enabled() && !hak_pool_free_v1_reject_stats_enabled()) return;
if (hak_pool_v1_flatten_stats_enabled()) {
fprintf(stderr,
"[POOL_V1_FLAT] alloc_tls_hit=%llu alloc_fb=%llu free_tls_hit=%llu free_fb=%llu page_null=%llu not_mine=%llu other=%llu\n",
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.alloc_tls_hit,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.alloc_fallback_v1,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_tls_hit,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fallback_v1,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_page_null,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_not_mine,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.free_fb_other,
memory_order_relaxed));
}
// Phase POOL-FREE-V1-OPT Step 1: v2 reject stats
if (hak_pool_free_v1_reject_stats_enabled()) {
fprintf(stderr,
"[POOL_V2_REJECT] total=%llu ptr_null=%llu not_init=%llu desc_null=%llu mf2_null=%llu\n",
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.v2_reject_total,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.v2_reject_ptr_null,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.v2_reject_not_init,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.v2_reject_desc_null,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.v2_reject_mf2_null,
memory_order_relaxed));
}
}
__attribute__((destructor)) static void pool_v1_flatten_stats_destructor(void) {
@ -526,13 +561,44 @@ static inline int hak_pool_mid_lookup_v2_impl(void* ptr, size_t* out_size) {
}
static inline void hak_pool_free_fast_v2_impl(void* ptr, uintptr_t site_id) {
if (!ptr || !g_pool.initialized) return;
// Phase POOL-FREE-V1-OPT Step 1: Track v2 reject reasons
if (!ptr) {
if (__builtin_expect(hak_pool_free_v1_reject_stats_enabled(), 0)) {
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_ptr_null, 1, memory_order_relaxed);
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_total, 1, memory_order_relaxed);
}
return;
}
if (!g_pool.initialized) {
if (__builtin_expect(hak_pool_free_v1_reject_stats_enabled(), 0)) {
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_not_init, 1, memory_order_relaxed);
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_total, 1, memory_order_relaxed);
}
return;
}
if (g_mf2_enabled) {
MidPage* page = mf2_addr_to_page(ptr);
if (page) { mf2_free(ptr); return; }
// MF2 path but page was NULL → fallback to v1
if (__builtin_expect(hak_pool_free_v1_reject_stats_enabled(), 0)) {
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_mf2_null, 1, memory_order_relaxed);
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_total, 1, memory_order_relaxed);
}
return;
}
MidPageDesc* d = mid_desc_lookup_cached(ptr);
if (!d) return;
if (!d) {
// mid_desc_lookup failed → fallback to v1
if (__builtin_expect(hak_pool_free_v1_reject_stats_enabled(), 0)) {
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_desc_null, 1, memory_order_relaxed);
atomic_fetch_add_explicit(&g_pool_v1_flat_stats.v2_reject_total, 1, memory_order_relaxed);
}
return;
}
size_t sz = g_class_sizes[(int)d->class_idx];
if (sz == 0) return;
hak_pool_free(ptr, sz, site_id);