// tiny_route.h - Route Fingerprint (Box-boundary tracing, ultra-light) #pragma once #include #include #include #include "tiny_debug_ring.h" // Bits (keep <= 63 to stay in one 64-bit word) // 0: refill_enter // 1/2: ready_try/ready_hit // 3/4: mail_try/mail_hit // 5/6: sticky_try/sticky_hit // 7/8: hot_try/hot_hit // 9/10: bench_try/bench_hit // 11/12: reg_try/reg_hit // 13/14: adopt_try/adopt_hit // 15: mmap_path // 16: free_enter // 17: free_same_thread // 18: free_remote_transition // 19: first_free_transition // 20: mailbox_publish static __thread uint64_t g_route_fp __attribute__((unused)); static __thread uint32_t g_route_seq __attribute__((unused)); static __thread int g_route_active __attribute__((unused)); static int g_route_enable_env = -1; static int g_route_sample_lg = -1; static inline int route_enabled_runtime(void) { if (__builtin_expect(g_route_enable_env == -1, 0)) { const char* e = getenv("HAKMEM_ROUTE"); g_route_enable_env = (e && *e && *e != '0') ? 1 : 0; } return g_route_enable_env; } static inline uint32_t route_sample_mask(void) { if (__builtin_expect(g_route_sample_lg == -1, 0)) { const char* e = getenv("HAKMEM_ROUTE_SAMPLE_LG"); int lg = (e && *e) ? atoi(e) : 10; // 1/1024 既定 if (lg < 0) lg = 0; if (lg > 24) lg = 24; g_route_sample_lg = lg; } return (g_route_sample_lg >= 31) ? 0xFFFFFFFFu : ((1u << g_route_sample_lg) - 1u); } #if HAKMEM_BUILD_RELEASE && !HAKMEM_ROUTE #define ROUTE_BEGIN(cls) do { (void)(cls); } while(0) #define ROUTE_MARK(bit) do { (void)(bit); } while(0) #define ROUTE_COMMIT(cls, tag) do { (void)(cls); (void)(tag); } while(0) static inline void route_free_commit(int class_idx, uint64_t bits, uint16_t tag) { (void)class_idx; (void)bits; (void)tag; } #else #define ROUTE_BEGIN(cls) do { \ if (__builtin_expect(!route_enabled_runtime(), 1)) { g_route_active = 0; break; } \ uint32_t m = route_sample_mask(); \ uint32_t s = ++g_route_seq; \ g_route_active = ((s & m) == 0u); \ g_route_fp = 0ull; \ (void)(cls); \ } while(0) #define ROUTE_MARK(bit) do { if (__builtin_expect(g_route_active, 0)) { g_route_fp |= (1ull << (bit)); } } while(0) #define ROUTE_COMMIT(cls, tag) do { \ if (__builtin_expect(g_route_active, 0)) { \ uintptr_t aux = ((uintptr_t)(tag & 0xFFFF) << 48) | (uintptr_t)(g_route_fp & 0x0000FFFFFFFFFFFFull); \ tiny_debug_ring_record(TINY_RING_EVENT_ROUTE, (uint16_t)(cls), (void*)(uintptr_t)g_route_fp, aux); \ g_route_active = 0; \ } \ } while(0) static inline void route_free_commit(int class_idx, uint64_t bits, uint16_t tag) { if (!route_enabled_runtime()) return; uintptr_t aux = ((uintptr_t)(tag & 0xFFFF) << 48) | (uintptr_t)(bits & 0x0000FFFFFFFFFFFFull); tiny_debug_ring_record(TINY_RING_EVENT_ROUTE, (uint16_t)class_idx, (void*)(uintptr_t)bits, aux); } #endif // Note: Build-time gate removed to keep integration simple; runtime env controls activation.