// pagefault_telemetry_box.c - Box PageFaultTelemetry implementation #include "pagefault_telemetry_box.h" #include "../hakmem_tiny_stats_api.h" // For macros / flags #include #include // Per-thread state __thread uint64_t g_pf_bloom[PF_BUCKET_MAX][16] = {{0}}; __thread uint64_t g_pf_touch[PF_BUCKET_MAX] = {0}; // Enable flag (cached) int pagefault_telemetry_enabled(void) { static int g_enabled = -1; if (__builtin_expect(g_enabled == -1, 0)) { const char* env = getenv("HAKMEM_TINY_PAGEFAULT_TELEMETRY"); g_enabled = (env && *env && *env != '0') ? 1 : 0; } return g_enabled; } // Dump helper void pagefault_telemetry_dump(void) { if (!pagefault_telemetry_enabled()) { return; } const char* dump_env = getenv("HAKMEM_TINY_PAGEFAULT_DUMP"); if (!(dump_env && *dump_env && *dump_env != '0')) { return; } fprintf(stderr, "\n========== Box PageFaultTelemetry: Tiny Page Touch Stats ==========\n"); fprintf(stderr, "Note: pages ~= popcount(1024-bit bloom); collisions → 下限近似値\n\n"); fprintf(stderr, "%-5s %12s %12s %12s\n", "Bucket", "touches", "approx_pages", "touches/page"); fprintf(stderr, "------|------------|------------|------------\n"); for (int b = 0; b < PF_BUCKET_MAX; b++) { uint64_t touches = g_pf_touch[b]; if (touches == 0) { continue; } uint64_t bits = 0; for (int w = 0; w < 16; w++) { bits += (uint64_t)__builtin_popcountll(g_pf_bloom[b][w]); } double pages = (double)bits; double tpp = pages > 0.0 ? (double)touches / pages : 0.0; const char* name = NULL; char buf[8]; if (b < PF_BUCKET_TINY_LIMIT) { snprintf(buf, sizeof(buf), "C%d", b); name = buf; } else if (b == PF_BUCKET_MID) { name = "MID"; } else if (b == PF_BUCKET_L25) { name = "L25"; } else if (b == PF_BUCKET_SS_META) { name = "SSM"; } else { snprintf(buf, sizeof(buf), "X%d", b); name = buf; } fprintf(stderr, "%-5s %12llu %12llu %12.1f\n", name, (unsigned long long)touches, (unsigned long long)bits, tpp); } fprintf(stderr, "===============================================================\n\n"); } // Auto-dump at thread exit (bench系で 1 回だけ実行される想定) static void pagefault_telemetry_atexit(void) __attribute__((destructor)); static void pagefault_telemetry_atexit(void) { pagefault_telemetry_dump(); }