2025-12-13 18:04:14 +09:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
#include "tiny_static_route_box.h"
|
|
|
|
|
#include "smallobject_policy_v7_box.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdatomic.h>
|
|
|
|
|
|
2025-12-13 18:46:11 +09:00
|
|
|
TinyStaticRoute g_tiny_static_route = {.inited = ATOMIC_VAR_INIT(0)};
|
2025-12-13 18:04:14 +09:00
|
|
|
|
2025-12-13 18:46:11 +09:00
|
|
|
static _Atomic int static_route_cached_enabled = -1; // -1 = uninitialized
|
2025-12-13 18:04:14 +09:00
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
2025-12-13 18:46:11 +09:00
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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()) {
|
2025-12-13 18:46:11 +09:00
|
|
|
atomic_store_explicit(&g_tiny_static_route.inited, 0, memory_order_release);
|
2025-12-13 18:04:14 +09:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-13 18:46:11 +09:00
|
|
|
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
|
2025-12-13 18:04:14 +09:00
|
|
|
int expected = 0;
|
2025-12-13 18:46:11 +09:00
|
|
|
if (!atomic_compare_exchange_strong_explicit(&g_tiny_static_route.inited, &expected, -1,
|
|
|
|
|
memory_order_acq_rel,
|
|
|
|
|
memory_order_relaxed)) {
|
2025-12-13 18:04:14 +09:00
|
|
|
// Someone else is initializing or already initialized
|
2025-12-13 18:46:11 +09:00
|
|
|
while (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == -1) {
|
2025-12-13 18:04:14 +09:00
|
|
|
__builtin_ia32_pause();
|
|
|
|
|
}
|
2025-12-13 18:46:11 +09:00
|
|
|
return atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) == 1;
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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) {
|
2025-12-13 18:46:11 +09:00
|
|
|
if ((unsigned)class_idx >= 8u) {
|
|
|
|
|
return SMALL_ROUTE_LEGACY;
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
2025-12-13 18:46:11 +09:00
|
|
|
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1) {
|
|
|
|
|
if (!tiny_static_route_init_once()) {
|
|
|
|
|
return SMALL_ROUTE_LEGACY;
|
|
|
|
|
}
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
|
|
|
|
return g_tiny_static_route.route_kind[class_idx];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tiny_static_route_refresh_from_env(void) {
|
2025-12-13 18:46:11 +09:00
|
|
|
// 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);
|
2025-12-13 18:04:14 +09:00
|
|
|
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) {
|
2025-12-13 18:46:11 +09:00
|
|
|
int cached = atomic_load_explicit(&static_route_cached_enabled, memory_order_acquire);
|
|
|
|
|
if (__builtin_expect(cached >= 0, 1)) {
|
|
|
|
|
return cached;
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
2025-12-13 18:46:11 +09:00
|
|
|
|
|
|
|
|
int enabled = static_route_should_be_enabled();
|
|
|
|
|
atomic_store_explicit(&static_route_cached_enabled, enabled, memory_order_release);
|
|
|
|
|
return enabled;
|
2025-12-13 18:04:14 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__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
|
2025-12-13 18:46:11 +09:00
|
|
|
if (atomic_load_explicit(&g_tiny_static_route.inited, memory_order_acquire) != 1 &&
|
|
|
|
|
tiny_static_route_enabled()) {
|
2025-12-13 18:04:14 +09:00
|
|
|
tiny_static_route_init_once();
|
|
|
|
|
}
|
|
|
|
|
}
|