Files
hakmem/core/box/pool_stats_box.h
Moe Charm (CI) b01c99f209 Phase: Pool API Modularization - Steps 1-2
Extract configuration, statistics, and caching boxes from pool_api.inc.h

Step 1: pool_config_box.h (60 lines)
  - All ENV gate predicates (hak_pool_v2_enabled, hak_pool_v1_flatten_enabled, etc)
  - Lazy static int cache pattern (matches tiny_heap_env_box.h style)
  - Zero dependencies (lowest-level box)

Step 2a: pool_stats_box.h (90 lines)
  - PoolV1FlattenStats structure with multi-phase support
  - pool_v1_flat_stats_dump() with phase-aware output
  - Destructor hook for automatic dumping on exit
  - Multi-phase design: supports future phases without refactoring

Step 2b: pool_mid_desc_cache_box.h (60 lines)
  - MidDescCache structure (TLS-local single-entry LRU)
  - mid_desc_lookup_cached() with fast TLS hit path
  - Minimal external dependency: mid_desc_lookup from pool_mid_desc.inc.h

Result: pool_api.inc.h reduced from 1050+ lines to ~950 lines
  Still contains: alloc/free implementations, helpers (next steps)

Build:  Clean (no warnings)
Test:  Benchmark passes (8.5M ops/s)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 21:39:18 +09:00

105 lines
5.5 KiB
C

// pool_stats_box.h — Box: Pool Statistics & Monitoring
//
// Purpose: Pool allocator statistics tracking for all phases
// Pattern: Atomic counters + dump on destructor
// Multi-phase design: Supports future phase extensions (POOL-MID-DN-BATCH, etc)
#ifndef POOL_STATS_BOX_H
#define POOL_STATS_BOX_H
#include "pool_config_box.h" // For hak_pool_v1_flatten_stats_enabled(), etc
#include <stdio.h>
#include <stdint.h>
#include <stdatomic.h>
// ============================================================================
// Pool V1 Flatten Statistics
// ============================================================================
// Tracks allocation/free path hits + rejection reasons
// Multi-phase design: Each phase adds fields without disrupting others
typedef struct PoolV1FlattenStats {
// Flatten hot path stats (basic alloc/free tracking)
_Atomic uint64_t alloc_tls_hit;
_Atomic uint64_t alloc_fallback_v1;
_Atomic uint64_t free_tls_hit;
_Atomic uint64_t free_fallback_v1;
_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
// Phase POOL-FREE-V1-OPT Step 2: fast split stats
_Atomic uint64_t fastsplit_fast_hit; // Fast path taken
_Atomic uint64_t fastsplit_slow_hit; // Slow path taken (fast predicate failed)
_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;
// Global stats instance (shared by all phases)
static PoolV1FlattenStats g_pool_v1_flat_stats = {0};
// ============================================================================
// Statistics Dump & Monitoring
// ============================================================================
static inline void pool_v1_flat_stats_dump(void) {
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));
}
// Phase POOL-FREE-V1-OPT Step 2: fastsplit stats
if (hak_pool_v1_flatten_stats_enabled() && hak_pool_v1_free_fastsplit_enabled()) {
fprintf(stderr,
"[POOL_V1_FASTSPLIT] fast_hit=%llu slow_hit=%llu\n",
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.fastsplit_fast_hit,
memory_order_relaxed),
(unsigned long long)atomic_load_explicit(&g_pool_v1_flat_stats.fastsplit_slow_hit,
memory_order_relaxed));
}
}
// Dump stats on program exit (destructor attribute)
__attribute__((destructor)) static void pool_v1_flatten_stats_destructor(void) {
pool_v1_flat_stats_dump();
}
#endif // POOL_STATS_BOX_H