// tiny_class_stats_box.c - Thread-local stats storage for Tiny classes #include "tiny_class_stats_box.h" #include "tiny_mem_stats_box.h" #include #include __thread TinyClassStatsThread g_tiny_class_stats = {0}; _Atomic uint64_t g_tiny_class_stats_uc_miss_global[TINY_NUM_CLASSES] = {0}; _Atomic uint64_t g_tiny_class_stats_warm_hit_global[TINY_NUM_CLASSES] = {0}; _Atomic uint64_t g_tiny_class_stats_shared_lock_global[TINY_NUM_CLASSES] = {0}; _Atomic uint64_t g_tiny_class_stats_tls_carve_attempt_global[TINY_NUM_CLASSES] = {0}; _Atomic uint64_t g_tiny_class_stats_tls_carve_success_global[TINY_NUM_CLASSES] = {0}; static _Atomic int g_tiny_class_stats_mem_recorded = 0; static void tiny_class_stats_record_mem_once(void) { if (atomic_exchange_explicit(&g_tiny_class_stats_mem_recorded, 1, memory_order_acq_rel) == 0) { tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats)); tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats_uc_miss_global)); tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats_warm_hit_global)); tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats_shared_lock_global)); tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats_tls_carve_attempt_global)); tiny_mem_stats_add_policy_stats((ssize_t)sizeof(g_tiny_class_stats_tls_carve_success_global)); } } void tiny_class_stats_reset_thread(void) { memset(&g_tiny_class_stats, 0, sizeof(g_tiny_class_stats)); } void tiny_class_stats_snapshot_thread(TinyClassStatsThread* out) { if (!out) return; tiny_class_stats_record_mem_once(); memcpy(out, &g_tiny_class_stats, sizeof(*out)); } void tiny_class_stats_snapshot_global(TinyClassStatsThread* out) { if (!out) return; tiny_class_stats_record_mem_once(); for (int i = 0; i < TINY_NUM_CLASSES; i++) { out->uc_miss[i] = atomic_load_explicit(&g_tiny_class_stats_uc_miss_global[i], memory_order_relaxed); out->warm_hit[i] = atomic_load_explicit(&g_tiny_class_stats_warm_hit_global[i], memory_order_relaxed); out->shared_lock[i] = atomic_load_explicit(&g_tiny_class_stats_shared_lock_global[i], memory_order_relaxed); out->tls_carve_attempt[i] = atomic_load_explicit( &g_tiny_class_stats_tls_carve_attempt_global[i], memory_order_relaxed); out->tls_carve_success[i] = atomic_load_explicit( &g_tiny_class_stats_tls_carve_success_global[i], memory_order_relaxed); } } static void tiny_class_stats_dump_common(FILE* out, const char* tag, const TinyClassStatsThread* stats) { if (!(out && stats)) return; fprintf(out, "%s class uc_miss warm_hit shared_lock tls_carve_attempt tls_carve_success\n", tag ? tag : "[STATS]"); for (int c = 0; c < TINY_NUM_CLASSES; c++) { if (stats->uc_miss[c] || stats->warm_hit[c] || stats->shared_lock[c] || stats->tls_carve_attempt[c] || stats->tls_carve_success[c]) { fprintf(out, " C%d: %llu %llu %llu %llu %llu\n", c, (unsigned long long)stats->uc_miss[c], (unsigned long long)stats->warm_hit[c], (unsigned long long)stats->shared_lock[c], (unsigned long long)stats->tls_carve_attempt[c], (unsigned long long)stats->tls_carve_success[c]); } } } void tiny_class_stats_dump_thread(FILE* out, const char* tag) { TinyClassStatsThread snap = {0}; tiny_class_stats_snapshot_thread(&snap); tiny_class_stats_dump_common(out, tag ? tag : "[THREAD_STATS]", &snap); } void tiny_class_stats_dump_global(FILE* out, const char* tag) { TinyClassStatsThread snap = {0}; tiny_class_stats_snapshot_global(&snap); tiny_class_stats_dump_common(out, tag ? tag : "[GLOBAL_STATS]", &snap); }