#define _GNU_SOURCE #include "wrapper_env_box.h" #include #include wrapper_env_cfg_t g_wrapper_env = {.inited = 0, .step_trace = 0, .ld_safe_mode = 1, .free_wrap_trace = 0, .wrap_diag = 0, .wrap_shape = 0}; static inline int env_flag(const char* name, int def) { const char* e = getenv(name); if (!e || *e == '\0') return def; return (*e != '0'); } static inline int env_int(const char* name, int def) { const char* e = getenv(name); if (!e || *e == '\0') return def; char* end; long val = strtol(e, &end, 10); return (end != e) ? (int)val : def; } void wrapper_env_init_once(void) { // Atomic CAS to ensure exactly-once initialization static _Atomic int init_started = 0; int expected = 0; if (!atomic_compare_exchange_strong_explicit(&init_started, &expected, 1, memory_order_acq_rel, memory_order_relaxed)) { // Someone else is initializing or already initialized // Spin until they're done while (!__builtin_expect(g_wrapper_env.inited, 1)) { __builtin_ia32_pause(); } return; } // We own the initialization g_wrapper_env.step_trace = env_flag("HAKMEM_STEP_TRACE", 0); g_wrapper_env.ld_safe_mode = env_int("HAKMEM_LD_SAFE", 1); g_wrapper_env.free_wrap_trace = env_flag("HAKMEM_FREE_WRAP_TRACE", 0); g_wrapper_env.wrap_diag = env_flag("HAKMEM_WRAP_DIAG", 0); g_wrapper_env.wrap_shape = env_flag("HAKMEM_WRAP_SHAPE", 0); // Mark as initialized last with memory barrier atomic_store_explicit(&g_wrapper_env.inited, 1, memory_order_release); } void wrapper_env_refresh_from_env(void) { // Ensure base init happened (constructor may have already done this) if (!g_wrapper_env.inited) { wrapper_env_init_once(); return; } // Re-read ENV (bench_profile may have injected defaults via putenv) g_wrapper_env.step_trace = env_flag("HAKMEM_STEP_TRACE", 0); g_wrapper_env.ld_safe_mode = env_int("HAKMEM_LD_SAFE", 1); g_wrapper_env.free_wrap_trace = env_flag("HAKMEM_FREE_WRAP_TRACE", 0); g_wrapper_env.wrap_diag = env_flag("HAKMEM_WRAP_DIAG", 0); g_wrapper_env.wrap_shape = env_flag("HAKMEM_WRAP_SHAPE", 0); atomic_store_explicit(&g_wrapper_env.inited, 1, memory_order_release); } __attribute__((constructor(101))) static void wrapper_env_ctor(void) { // Constructor priority 101 runs early (libc uses 100+) // This ensures initialization before any malloc calls if (!g_wrapper_env.inited) { wrapper_env_init_once(); } }