Phase POOL-MID-DN-BATCH Step 3: Statistics counters for deferred inuse_dec
This commit is contained in:
69
core/box/pool_mid_inuse_deferred_stats_box.h
Normal file
69
core/box/pool_mid_inuse_deferred_stats_box.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// pool_mid_inuse_deferred_stats_box.h — Box: Deferred inuse_dec Statistics
|
||||||
|
//
|
||||||
|
// Purpose: Track deferred inuse_dec performance counters
|
||||||
|
// Pattern: Atomic counters with destructor dump
|
||||||
|
// Phase: POOL-MID-DN-BATCH Step 5
|
||||||
|
//
|
||||||
|
// Counters:
|
||||||
|
// - mid_inuse_deferred_hit: Total deferred decrements (hot path)
|
||||||
|
// - drain_calls: Number of drain operations (cold path)
|
||||||
|
// - pages_drained: Total pages processed in drain
|
||||||
|
// - empty_transitions: Pages that triggered DONTNEED
|
||||||
|
|
||||||
|
#ifndef POOL_MID_INUSE_DEFERRED_STATS_BOX_H
|
||||||
|
#define POOL_MID_INUSE_DEFERRED_STATS_BOX_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Statistics structure
|
||||||
|
typedef struct {
|
||||||
|
_Atomic uint64_t mid_inuse_deferred_hit; // Total deferred decrements
|
||||||
|
_Atomic uint64_t drain_calls; // Number of drain calls
|
||||||
|
_Atomic uint64_t pages_drained; // Total pages drained
|
||||||
|
_Atomic uint64_t empty_transitions; // Pages that went to 0
|
||||||
|
} MidInuseDeferredStats;
|
||||||
|
|
||||||
|
// Global stats instance
|
||||||
|
static MidInuseDeferredStats g_mid_inuse_deferred_stats;
|
||||||
|
|
||||||
|
// Stats increment macros (inline for hot path)
|
||||||
|
#define MID_INUSE_DEFERRED_STAT_INC(field) \
|
||||||
|
atomic_fetch_add_explicit(&g_mid_inuse_deferred_stats.field, 1, memory_order_relaxed)
|
||||||
|
|
||||||
|
#define MID_INUSE_DEFERRED_STAT_ADD(field, n) \
|
||||||
|
atomic_fetch_add_explicit(&g_mid_inuse_deferred_stats.field, (n), memory_order_relaxed)
|
||||||
|
|
||||||
|
// Dump stats on exit (if ENV var set)
|
||||||
|
static void mid_inuse_deferred_stats_dump(void) {
|
||||||
|
// Only dump if deferred is enabled
|
||||||
|
const char* e = getenv("HAKMEM_POOL_MID_INUSE_DEFERRED");
|
||||||
|
if (!e || *e != '1') return;
|
||||||
|
|
||||||
|
uint64_t hits = atomic_load_explicit(&g_mid_inuse_deferred_stats.mid_inuse_deferred_hit, memory_order_relaxed);
|
||||||
|
uint64_t drains = atomic_load_explicit(&g_mid_inuse_deferred_stats.drain_calls, memory_order_relaxed);
|
||||||
|
uint64_t pages = atomic_load_explicit(&g_mid_inuse_deferred_stats.pages_drained, memory_order_relaxed);
|
||||||
|
uint64_t empties = atomic_load_explicit(&g_mid_inuse_deferred_stats.empty_transitions, memory_order_relaxed);
|
||||||
|
|
||||||
|
if (hits > 0 || drains > 0) {
|
||||||
|
fprintf(stderr, "\n=== Mid Inuse Deferred Stats ===\n");
|
||||||
|
fprintf(stderr, "Deferred hits: %lu\n", hits);
|
||||||
|
fprintf(stderr, "Drain calls: %lu\n", drains);
|
||||||
|
fprintf(stderr, "Pages drained: %lu\n", pages);
|
||||||
|
fprintf(stderr, "Empty transitions: %lu\n", empties);
|
||||||
|
if (drains > 0) {
|
||||||
|
fprintf(stderr, "Avg pages/drain: %.2f\n", (double)pages / (double)drains);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "================================\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register destructor to dump stats on exit
|
||||||
|
static void mid_inuse_deferred_stats_init(void) __attribute__((constructor));
|
||||||
|
static void mid_inuse_deferred_stats_init(void) {
|
||||||
|
atexit(mid_inuse_deferred_stats_dump);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // POOL_MID_INUSE_DEFERRED_STATS_BOX_H
|
||||||
Reference in New Issue
Block a user