Files
hakmem/core/box/tiny_static_route_box.c

134 lines
4.7 KiB
C
Raw Normal View History

#define _GNU_SOURCE
#include "tiny_static_route_box.h"
#include "smallobject_policy_v7_box.h"
#include <stdlib.h>
#include <stdatomic.h>
TinyStaticRoute g_tiny_static_route = {.inited = ATOMIC_VAR_INIT(0)};
static _Atomic int static_route_cached_enabled = -1; // -1 = uninitialized
// Check if static routing should be enabled
// (Returns 0 if learner is active, or if ENV is explicitly off)
static inline int static_route_should_be_enabled(void) {
const char* e = getenv("HAKMEM_TINY_STATIC_ROUTE");
// Explicit disable
if (e && *e == '0') return 0;
// If v7 learner is enabled, force disable (static route doesn't track learner updates).
// Mirrors smallobject_policy_v7.c::learner_v7_enabled():
// - If HAKMEM_SMALL_LEARNER_V7_ENABLED=0 → learner disabled
// - Else learner enabled iff HAKMEM_SMALL_HEAP_V7_ENABLED is enabled
{
const char* learner_e = getenv("HAKMEM_SMALL_LEARNER_V7_ENABLED");
if (!(learner_e && *learner_e && *learner_e == '0')) {
const char* v7_e = getenv("HAKMEM_SMALL_HEAP_V7_ENABLED");
if (v7_e && *v7_e && *v7_e != '0') {
return 0; // Learner ON → static route OFF
}
}
}
// Explicit enable or default OFF
return (e && *e != '0') ? 1 : 0;
}
int tiny_static_route_init_once(void) {
// Check if static routing is enabled
if (!static_route_should_be_enabled()) {
atomic_store_explicit(&g_tiny_static_route.inited, 0, memory_order_release);
return 0;
}
int state = atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire);
if (__builtin_expect(state == 1, 1)) {
return 1;
}
if (__builtin_expect(state == -1, 0)) {
while (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == -1) {
__builtin_ia32_pause();
}
return atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == 1;
}
// Try to become the initializer: 0 → -1
int expected = 0;
if (!atomic_compare_exchange_strong_explicit(&g_tiny_static_route.inited, &expected, -1,
memory_order_acq_rel,
memory_order_relaxed)) {
// Someone else is initializing or already initialized
while (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == -1) {
__builtin_ia32_pause();
}
return atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == 1;
}
// We own the initialization
SmallPolicyV7 tmp = {0};
small_policy_v7_init_from_env(&tmp);
// Copy static route table from policy snapshot (no learner update)
for (int i = 0; i < 8; i++) {
g_tiny_static_route.route_kind[i] = tmp.route_kind[i];
}
// Mark as initialized
atomic_store_explicit(&g_tiny_static_route.inited, 1, memory_order_release);
return 1;
}
SmallRouteKind tiny_static_route_get_kind(int class_idx) {
if ((unsigned)class_idx >= 8u) {
return SMALL_ROUTE_LEGACY;
}
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1) {
if (!tiny_static_route_init_once()) {
return SMALL_ROUTE_LEGACY;
}
}
return g_tiny_static_route.route_kind[class_idx];
}
void tiny_static_route_refresh_from_env(void) {
// Refresh cached enable flag first (bench_apply_profile sync).
int enabled = static_route_should_be_enabled();
atomic_store_explicit(&static_route_cached_enabled, enabled, memory_order_release);
if (!enabled) {
atomic_store_explicit(&g_tiny_static_route.inited, 0, memory_order_release);
return;
}
// Re-read route table from policy
SmallPolicyV7 tmp = {0};
small_policy_v7_init_from_env(&tmp);
for (int i = 0; i < 8; i++) {
g_tiny_static_route.route_kind[i] = tmp.route_kind[i];
}
atomic_store_explicit(&g_tiny_static_route.inited, 1, memory_order_release);
}
int tiny_static_route_enabled(void) {
int cached = atomic_load_explicit(&static_route_cached_enabled, memory_order_acquire);
if (__builtin_expect(cached >= 0, 1)) {
return cached;
}
int enabled = static_route_should_be_enabled();
atomic_store_explicit(&static_route_cached_enabled, enabled, memory_order_release);
return enabled;
}
__attribute__((constructor(102)))
static void tiny_static_route_ctor(void) {
// Constructor priority 102 runs after wrapper_env_ctor (101)
// Initialize static route table if enabled
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1 &&
tiny_static_route_enabled()) {
tiny_static_route_init_once();
}
}