// hak_kpi_util.inc.h — KPI measurement helpers (Linux / non-Linux) #ifndef HAK_KPI_UTIL_INC_H #define HAK_KPI_UTIL_INC_H #ifdef __linux__ // Latency histogram (simple buckets for P50/P95/P99) #define LATENCY_BUCKETS 100 static uint64_t g_latency_histogram[LATENCY_BUCKETS]; static uint64_t g_latency_samples = 0; // Baseline page faults (at init) static uint64_t g_baseline_soft_pf = 0; static uint64_t g_baseline_hard_pf = 0; static uint64_t g_baseline_rss_kb = 0; // Get page faults from /proc/self/stat static void get_page_faults(uint64_t* soft_pf, uint64_t* hard_pf) { FILE* f = fopen("/proc/self/stat", "r"); if (!f) { *soft_pf = 0; *hard_pf = 0; return; } unsigned long minflt = 0, majflt = 0; unsigned long dummy; char comm[256], state; (void)fscanf(f, "%lu %s %c %lu %lu %lu %lu %lu %lu %lu %lu %lu", &dummy, comm, &state, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &minflt, &dummy, &majflt); fclose(f); *soft_pf = minflt; *hard_pf = majflt; } // Get RSS from /proc/self/statm (in KB) static uint64_t get_rss_kb(void) { FILE* f = fopen("/proc/self/statm", "r"); if (!f) return 0; unsigned long size, resident; (void)fscanf(f, "%lu %lu", &size, &resident); fclose(f); long page_size = sysconf(_SC_PAGESIZE); return (resident * page_size) / 1024; // Convert to KB } static uint64_t calculate_percentile(double percentile) { if (g_latency_samples == 0) return 0; uint64_t target = (uint64_t)(g_latency_samples * percentile); uint64_t cumulative = 0; for (size_t i = 0; i < LATENCY_BUCKETS; i++) { cumulative += g_latency_histogram[i]; if (cumulative >= target) return i * 10; // Return bucket midpoint (ns) } return (LATENCY_BUCKETS - 1) * 10; } // Implement hak_get_kpi() void hak_get_kpi(hak_kpi_t* out) { memset(out, 0, sizeof(hak_kpi_t)); // Latency (from histogram) out->p50_alloc_ns = calculate_percentile(0.50); out->p95_alloc_ns = calculate_percentile(0.95); out->p99_alloc_ns = calculate_percentile(0.99); // Page Faults (delta from baseline) uint64_t soft_pf, hard_pf; get_page_faults(&soft_pf, &hard_pf); out->soft_page_faults = soft_pf - g_baseline_soft_pf; out->hard_page_faults = hard_pf - g_baseline_hard_pf; // RSS (delta from baseline, in MB) uint64_t rss_kb = get_rss_kb(); int64_t rss_delta_kb = (int64_t)rss_kb - (int64_t)g_baseline_rss_kb; out->rss_delta_mb = rss_delta_kb / 1024; } #else // Non-Linux: stub implementation void hak_get_kpi(hak_kpi_t* out) { memset(out, 0, sizeof(hak_kpi_t)); } #endif #endif // HAK_KPI_UTIL_INC_H