Priority-2 ENV Cache: Shared Pool Acquire (5変数追加、5箇所置換)

【追加ENV変数】
- HAKMEM_SS_EMPTY_REUSE (default: 1)
- HAKMEM_SS_EMPTY_SCAN_LIMIT (default: 32)
- HAKMEM_SS_ACQUIRE_DEBUG (default: 0)
- HAKMEM_TINY_TENSION_DRAIN_ENABLE (default: 1)
- HAKMEM_TINY_TENSION_DRAIN_THRESHOLD (default: 1024)

【置換ファイル】
- core/hakmem_shared_pool_acquire.c (5箇所 → ENV Cache)

【変更詳細】
1. ENV Cache (hakmem_env_cache.h):
   - 構造体に5変数追加 (41→46変数)
   - hakmem_env_cache_init()に初期化追加
   - アクセサマクロ5個追加
   - カウント更新: 41→46

2. hakmem_shared_pool_acquire.c:
   - getenv("HAKMEM_SS_EMPTY_REUSE") → HAK_ENV_SS_EMPTY_REUSE()
   - getenv("HAKMEM_SS_EMPTY_SCAN_LIMIT") → HAK_ENV_SS_EMPTY_SCAN_LIMIT()
   - getenv("HAKMEM_SS_ACQUIRE_DEBUG") → HAK_ENV_SS_ACQUIRE_DEBUG()
   - getenv("HAKMEM_TINY_TENSION_DRAIN_ENABLE") → HAK_ENV_TINY_TENSION_DRAIN_ENABLE()
   - getenv("HAKMEM_TINY_TENSION_DRAIN_THRESHOLD") → HAK_ENV_TINY_TENSION_DRAIN_THRESHOLD()
   - #include "hakmem_env_cache.h" 追加

【効果】
- Shared Pool Acquire warm pathからgetenv()呼び出しを完全排除
- Lock-free Stage2のgetenv()オーバーヘッド削減

【テスト】
 make shared → 成功
 /tmp/test_mixed3_final → PASSED

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-02 20:51:50 +09:00
parent b80b3d445e
commit c482722705
2 changed files with 46 additions and 31 deletions

View File

@ -74,6 +74,13 @@ typedef struct {
int ss_prewarm_debug; // HAKMEM_SS_PREWARM_DEBUG (default: 0)
int prewarm_superslabs; // HAKMEM_PREWARM_SUPERSLABS (default: 0)
// ===== Warm Path: Shared Pool Acquire (5 variables) =====
int ss_empty_reuse; // HAKMEM_SS_EMPTY_REUSE (default: 1)
int ss_empty_scan_limit; // HAKMEM_SS_EMPTY_SCAN_LIMIT (default: 32)
int ss_acquire_debug; // HAKMEM_SS_ACQUIRE_DEBUG (default: 0)
int tiny_tension_drain_enable; // HAKMEM_TINY_TENSION_DRAIN_ENABLE (default: 1)
int tiny_tension_drain_threshold; // HAKMEM_TINY_TENSION_DRAIN_THRESHOLD (default: 1024)
} HakEnvCache;
// Global cache instance (initialized once at startup)
@ -230,10 +237,31 @@ static inline void hakmem_env_cache_init(void) {
g_hak_env_cache.prewarm_superslabs = (e && *e) ? atoi(e) : 0;
}
// ===== Warm Path: Shared Pool Acquire =====
{
const char* e;
e = getenv("HAKMEM_SS_EMPTY_REUSE");
g_hak_env_cache.ss_empty_reuse = (e && *e && *e == '0') ? 0 : 1; // default: 1 (ON)
e = getenv("HAKMEM_SS_EMPTY_SCAN_LIMIT");
g_hak_env_cache.ss_empty_scan_limit = (e && *e) ? atoi(e) : 32; // default: 32
e = getenv("HAKMEM_SS_ACQUIRE_DEBUG");
g_hak_env_cache.ss_acquire_debug = (e && *e && *e != '0') ? 1 : 0;
e = getenv("HAKMEM_TINY_TENSION_DRAIN_ENABLE");
g_hak_env_cache.tiny_tension_drain_enable = (e == NULL || atoi(e) != 0) ? 1 : 0; // default: 1 (ON)
e = getenv("HAKMEM_TINY_TENSION_DRAIN_THRESHOLD");
g_hak_env_cache.tiny_tension_drain_threshold = (e && *e) ? atoi(e) : 1024; // default: 1024
if (g_hak_env_cache.tiny_tension_drain_threshold < 64) g_hak_env_cache.tiny_tension_drain_threshold = 64;
if (g_hak_env_cache.tiny_tension_drain_threshold > 65536) g_hak_env_cache.tiny_tension_drain_threshold = 65536;
}
#if !HAKMEM_BUILD_RELEASE
// Debug: Print cache summary (stderr only)
if (!g_hak_env_cache.quiet) {
fprintf(stderr, "[ENV_CACHE_INIT] Parsed %d ENV variables at startup\n", 41);
fprintf(stderr, "[ENV_CACHE_INIT] Parsed %d ENV variables at startup\n", 46);
fprintf(stderr, "[ENV_CACHE_INIT] Hot path syscalls eliminated: ~2000/sec → 0/sec\n");
fflush(stderr);
}
@ -286,4 +314,11 @@ static inline void hakmem_env_cache_init(void) {
#define HAK_ENV_SS_PREWARM_DEBUG() (g_hak_env_cache.ss_prewarm_debug)
#define HAK_ENV_PREWARM_SUPERSLABS() (g_hak_env_cache.prewarm_superslabs)
// Warm path: Shared Pool Acquire
#define HAK_ENV_SS_EMPTY_REUSE() (g_hak_env_cache.ss_empty_reuse)
#define HAK_ENV_SS_EMPTY_SCAN_LIMIT() (g_hak_env_cache.ss_empty_scan_limit)
#define HAK_ENV_SS_ACQUIRE_DEBUG() (g_hak_env_cache.ss_acquire_debug)
#define HAK_ENV_TINY_TENSION_DRAIN_ENABLE() (g_hak_env_cache.tiny_tension_drain_enable)
#define HAK_ENV_TINY_TENSION_DRAIN_THRESHOLD() (g_hak_env_cache.tiny_tension_drain_threshold)
#endif // HAKMEM_ENV_CACHE_H

View File

@ -7,6 +7,7 @@
#include "box/tls_sll_drain_box.h"
#include "box/tls_slab_reuse_guard_box.h"
#include "hakmem_policy.h"
#include "hakmem_env_cache.h" // Priority-2: ENV cache
#include <stdlib.h>
#include <stdio.h>
@ -18,12 +19,8 @@
static inline int
sp_acquire_from_empty_scan(int class_idx, SuperSlab** ss_out, int* slab_idx_out, int dbg_acquire)
{
static int empty_reuse_enabled = -1;
if (__builtin_expect(empty_reuse_enabled == -1, 0)) {
const char* e = getenv("HAKMEM_SS_EMPTY_REUSE");
empty_reuse_enabled = (e && *e && *e == '0') ? 0 : 1; // default ON
}
// Priority-2: Use cached ENV
int empty_reuse_enabled = HAK_ENV_SS_EMPTY_REUSE();
if (!empty_reuse_enabled) {
return -1;
}
@ -32,11 +29,8 @@ sp_acquire_from_empty_scan(int class_idx, SuperSlab** ss_out, int* slab_idx_out,
extern int g_super_reg_class_size[TINY_NUM_CLASSES];
int reg_size = (class_idx < TINY_NUM_CLASSES) ? g_super_reg_class_size[class_idx] : 0;
static int scan_limit = -1;
if (__builtin_expect(scan_limit == -1, 0)) {
const char* e = getenv("HAKMEM_SS_EMPTY_SCAN_LIMIT");
scan_limit = (e && *e) ? atoi(e) : 32; // default: scan first 32 SuperSlabs (Phase 9-2 tuning)
}
// Priority-2: Use cached ENV
int scan_limit = HAK_ENV_SS_EMPTY_SCAN_LIMIT();
if (scan_limit > reg_size) scan_limit = reg_size;
// Stage 0.5 hit counter for visualization
@ -118,11 +112,8 @@ shared_pool_acquire_slab(int class_idx, SuperSlab** ss_out, int* slab_idx_out)
// Debug logging / stage stats
#if !HAKMEM_BUILD_RELEASE
static int dbg_acquire = -1;
if (__builtin_expect(dbg_acquire == -1, 0)) {
const char* e = getenv("HAKMEM_SS_ACQUIRE_DEBUG");
dbg_acquire = (e && *e && *e != '0') ? 1 : 0;
}
// Priority-2: Use cached ENV
int dbg_acquire = HAK_ENV_SS_ACQUIRE_DEBUG();
#else
static const int dbg_acquire = 0;
#endif
@ -301,20 +292,9 @@ stage2_fallback:
// ENV: HAKMEM_TINY_TENSION_DRAIN_ENABLE=0 to disable (default=1)
// ENV: HAKMEM_TINY_TENSION_DRAIN_THRESHOLD=N to set threshold (default=1024)
{
static int tension_drain_enabled = -1;
static uint32_t tension_threshold = 1024;
if (tension_drain_enabled < 0) {
const char* env = getenv("HAKMEM_TINY_TENSION_DRAIN_ENABLE");
tension_drain_enabled = (env == NULL || atoi(env) != 0) ? 1 : 0;
const char* thresh_env = getenv("HAKMEM_TINY_TENSION_DRAIN_THRESHOLD");
if (thresh_env) {
tension_threshold = (uint32_t)atoi(thresh_env);
if (tension_threshold < 64) tension_threshold = 64;
if (tension_threshold > 65536) tension_threshold = 65536;
}
}
// Priority-2: Use cached ENV
int tension_drain_enabled = HAK_ENV_TINY_TENSION_DRAIN_ENABLE();
uint32_t tension_threshold = (uint32_t)HAK_ENV_TINY_TENSION_DRAIN_THRESHOLD();
if (tension_drain_enabled) {
extern __thread TinyTLSSLL g_tls_sll[TINY_NUM_CLASSES];