// page_stats_v6_box.h - Page Lifetime Stats for v6 (V6-HDR-0) // // Purpose: Collect page lifetime summary stats // - L2 (ColdIface) pushes stats on page retire // - L3 (Policy) aggregates for decision making // // Note: This box is NOT connected to hot path (no per-block stats) #ifndef HAKMEM_PAGE_STATS_V6_BOX_H #define HAKMEM_PAGE_STATS_V6_BOX_H #include #include // ============================================================================ // Page Lifetime Summary (pushed from L2 on retire) // ============================================================================ /// Summary of a single page's lifetime (passed to L3 on retire) typedef struct PageLifetimeSummaryV6 { uint8_t class_idx; // Size class (C4=4, C5=5, C6=6) uint32_t total_allocs; // Total allocs from this page uint32_t total_frees; // Total frees to this page uint32_t remote_frees; // Cross-thread frees uint64_t lifetime_ns; // Time from carve to retire (nanoseconds) uint64_t peak_used; // Max used during lifetime } PageLifetimeSummaryV6; // ============================================================================ // Aggregated Stats (L3 accumulator) // ============================================================================ /// Aggregated stats per class (atomics for thread safety) typedef struct PageStatsClassV6 { _Atomic uint64_t pages_created; // Total pages created _Atomic uint64_t pages_retired; // Total pages retired _Atomic uint64_t total_allocs; // Sum of allocs across all pages _Atomic uint64_t total_frees; // Sum of frees across all pages _Atomic uint64_t remote_frees; // Sum of remote frees _Atomic uint64_t sum_lifetime_ns; // Sum of lifetimes (for avg) _Atomic uint64_t max_lifetime_ns; // Max lifetime seen _Atomic uint64_t sum_peak_used; // Sum of peak_used (for avg utilization) } PageStatsClassV6; /// Global stats box typedef struct PageStatsV6 { PageStatsClassV6 by_class[8]; // Stats per class (indexed by class_idx) _Atomic uint64_t total_pages; // Total pages across all classes _Atomic uint64_t total_retires; // Total retires across all classes } PageStatsV6; // ============================================================================ // API // ============================================================================ /// Get global PageStatsV6 instance PageStatsV6* page_stats_v6_get(void); /// Record a page retire event (called by L2 ColdIface) /// @param summary: page lifetime summary void page_stats_v6_record_retire(const PageLifetimeSummaryV6* summary); /// Record a page creation event (called by L2 ColdIface) /// @param class_idx: size class void page_stats_v6_record_create(uint8_t class_idx); /// Dump stats to stderr (for debug) void page_stats_v6_dump(void); /// Reset all stats to zero void page_stats_v6_reset(void); // ============================================================================ // ENV Control // ============================================================================ /// ENV: HAKMEM_PAGE_STATS_V6_ENABLED (default: 0) /// When enabled, L2 calls page_stats_v6_record_*() on create/retire /// Check if page stats collection is enabled int page_stats_v6_enabled(void); // ============================================================================ // Computed Metrics // ============================================================================ /// Get average page lifetime for a class (returns 0 if no data) uint64_t page_stats_v6_avg_lifetime_ns(uint8_t class_idx); /// Get average peak utilization for a class (returns 0 if no data) /// @return: percentage (0-100) uint32_t page_stats_v6_avg_utilization(uint8_t class_idx); /// Get remote free ratio for a class (returns 0 if no data) /// @return: percentage (0-100) uint32_t page_stats_v6_remote_free_ratio(uint8_t class_idx); #endif // HAKMEM_PAGE_STATS_V6_BOX_H