Priority-2: ENV Cache - SuperSlab層の getenv() を完全置換

変更内容:
- tiny_superslab_alloc.inc.h: 1箇所の getenv() を置換
  (TINY_ALLOC_REMOTE_RELAX)
- tiny_superslab_free.inc.h: 7箇所の getenv() を置換
  (TINY_SLL_DIAG, TINY_ROUTE_FREE x2, TINY_FREE_TO_SS,
   SS_FREE_DEBUG x3, TINY_FREELIST_MASK)

効果: SuperSlab層からも syscall 完全排除

🤖 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:22:42 +09:00
parent 802b6e775f
commit 8336febdcb
2 changed files with 32 additions and 59 deletions

View File

@ -10,6 +10,7 @@
#include "hakmem_tiny_superslab_constants.h" #include "hakmem_tiny_superslab_constants.h"
#include "tiny_box_geometry.h" // Box 3: Geometry & Capacity Calculator" #include "tiny_box_geometry.h" // Box 3: Geometry & Capacity Calculator"
#include "tiny_debug_api.h" // Guard/failfast declarations #include "tiny_debug_api.h" // Guard/failfast declarations
#include "hakmem_env_cache.h" // Priority-2: ENV cache (eliminate syscalls)
// ============================================================================ // ============================================================================
// Phase 6.24: Allocate from SuperSlab slab (lazy freelist + linear allocation) // Phase 6.24: Allocate from SuperSlab slab (lazy freelist + linear allocation)
@ -298,15 +299,11 @@ static inline void* hak_tiny_alloc_superslab(int class_idx) {
} }
// Drain remote if needed (ownership-checked elsewhere) // Drain remote if needed (ownership-checked elsewhere)
// Priority-2: Use cached ENV (eliminate lazy-init syscall overhead)
if (meta) { if (meta) {
static int g_alloc_remote_relax = -1;
if (__builtin_expect(g_alloc_remote_relax == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_ALLOC_REMOTE_RELAX");
g_alloc_remote_relax = (e && *e && *e != '0') ? 1 : 0;
}
uintptr_t pending = atomic_load_explicit( uintptr_t pending = atomic_load_explicit(
&tls->ss->remote_heads[slab_idx], &tls->ss->remote_heads[slab_idx],
g_alloc_remote_relax ? memory_order_relaxed : memory_order_acquire); HAK_ENV_TINY_ALLOC_REMOTE_RELAX() ? memory_order_relaxed : memory_order_acquire);
if (__builtin_expect(pending != 0, 0)) { if (__builtin_expect(pending != 0, 0)) {
uint32_t self_tid = tiny_self_u32(); uint32_t self_tid = tiny_self_u32();
if (ss_owner_try_acquire(meta, self_tid)) { if (ss_owner_try_acquire(meta, self_tid)) {

View File

@ -10,6 +10,7 @@
#include "box/ptr_type_box.h" // Phase 10 #include "box/ptr_type_box.h" // Phase 10
#include "box/free_remote_box.h" #include "box/free_remote_box.h"
#include "box/free_local_box.h" #include "box/free_local_box.h"
#include "hakmem_env_cache.h" // Priority-2: ENV cache (eliminate syscalls)
// Phase 6.22-B: SuperSlab fast free path // Phase 6.22-B: SuperSlab fast free path
static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) { static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
@ -129,14 +130,10 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
} }
// Header vs meta class mismatch detectorenv: HAKMEM_TINY_SLL_DIAG、初回数件のみ // Header vs meta class mismatch detectorenv: HAKMEM_TINY_SLL_DIAG、初回数件のみ
// Priority-2: Use cached ENV (eliminate lazy-init syscall overhead)
#if !HAKMEM_BUILD_RELEASE #if !HAKMEM_BUILD_RELEASE
do { do {
static int g_hdr_diag_en = -1; if (__builtin_expect(HAK_ENV_TINY_SLL_DIAG(), 0)) {
if (__builtin_expect(g_hdr_diag_en == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_SLL_DIAG");
g_hdr_diag_en = (e && *e && *e != '0') ? 1 : 0;
}
if (__builtin_expect(g_hdr_diag_en, 0)) {
uint8_t hdr = *(uint8_t*)base; uint8_t hdr = *(uint8_t*)base;
uint8_t expect = (uint8_t)(HEADER_MAGIC | (cls & HEADER_CLASS_MASK)); uint8_t expect = (uint8_t)(HEADER_MAGIC | (cls & HEADER_CLASS_MASK));
if (__builtin_expect(hdr != expect, 0)) { if (__builtin_expect(hdr != expect, 0)) {
@ -197,23 +194,17 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
extern unsigned long long g_remote_free_transitions[]; extern unsigned long long g_remote_free_transitions[];
g_remote_free_transitions[cls]++; g_remote_free_transitions[cls]++;
// Free-side route: remote transition observed // Free-side route: remote transition observed
// Priority-2: Use cached ENV (eliminate lazy-init syscall overhead)
do { do {
static int g_route_free = -1; if (__builtin_expect(g_route_free == -1, 0)) { if (HAK_ENV_TINY_ROUTE_FREE()) route_free_commit((int)cls, (1ull<<18), 0xE2);
const char* e = getenv("HAKMEM_TINY_ROUTE_FREE");
g_route_free = (e && *e && *e != '0') ? 1 : 0; }
if (g_route_free) route_free_commit((int)cls, (1ull<<18), 0xE2);
} while (0); } while (0);
} }
return; return;
} }
// Optional: MidTC (TLS tcache for 128..1024B) — allow bypass via env HAKMEM_TINY_FREE_TO_SS=1 // Optional: MidTC (TLS tcache for 128..1024B) — allow bypass via env HAKMEM_TINY_FREE_TO_SS=1
// Priority-2: Use cached ENV (eliminate lazy-init syscall overhead)
do { do {
static int g_free_to_ss = -1; if (!HAK_ENV_TINY_FREE_TO_SS()) {
if (__builtin_expect(g_free_to_ss == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_FREE_TO_SS");
g_free_to_ss = (e && *e && *e != '0') ? 1 : 0; // default OFF
}
if (!g_free_to_ss) {
int mid_cls = (int)cls; int mid_cls = (int)cls;
if (midtc_enabled() && mid_cls >= 4) { if (midtc_enabled() && mid_cls >= 4) {
if (midtc_push(mid_cls, base)) { if (midtc_push(mid_cls, base)) {
@ -226,17 +217,13 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
} }
} while (0); } while (0);
// DEBUG LOGGING - Track freelist operations // DEBUG LOGGING - Track freelist operations
static __thread int dbg = -1; // Priority-2: Use cached ENV (eliminate lazy-init TLS overhead)
#if HAKMEM_BUILD_RELEASE
dbg = 0;
#else
if (__builtin_expect(dbg == -1, 0)) {
const char* e = getenv("HAKMEM_SS_FREE_DEBUG");
dbg = (e && *e && *e != '0') ? 1 : 0;
}
#endif
static __thread int free_count = 0; static __thread int free_count = 0;
if (dbg == 1 && (free_count++ % 1000) == 0) { #if !HAKMEM_BUILD_RELEASE
if (HAK_ENV_SS_FREE_DEBUG() && (free_count++ % 1000) == 0) {
#else
if (0) {
#endif
fprintf(stderr, "[FREE_LOCAL] cls=%u slab=%d meta->used=%u (before dec)\n", fprintf(stderr, "[FREE_LOCAL] cls=%u slab=%d meta->used=%u (before dec)\n",
cls, slab_idx, meta->used); cls, slab_idx, meta->used);
} }
@ -256,10 +243,8 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
#if HAKMEM_BUILD_RELEASE #if HAKMEM_BUILD_RELEASE
g_route_free = 0; g_route_free = 0;
#else #else
if (__builtin_expect(g_route_free == -1, 0)) { // Priority-2: Use cached ENV (eliminate lazy-init static overhead)
const char* e = getenv("HAKMEM_TINY_ROUTE_FREE"); g_route_free = HAK_ENV_TINY_ROUTE_FREE();
g_route_free = (e && *e && *e != '0') ? 1 : 0;
}
#endif #endif
if (g_route_free) route_free_commit(cls, (1ull<<19) | (1ull<<20), 0xE1); if (g_route_free) route_free_commit(cls, (1ull<<19) | (1ull<<20), 0xE1);
} while (0); } while (0);
@ -273,17 +258,12 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
// 空検出は別途(ホットパス除外) // 空検出は別途(ホットパス除外)
// Phase 12: slab empty → shared pool に返却 // Phase 12: slab empty → shared pool に返却
if (meta->used == 0) { if (meta->used == 0) {
// DEBUG LOGGING // DEBUG LOGGING - Priority-2: Use cached ENV (eliminate lazy-init TLS overhead)
static __thread int dbg = -1; #if !HAKMEM_BUILD_RELEASE
#if HAKMEM_BUILD_RELEASE if (HAK_ENV_SS_FREE_DEBUG()) {
dbg = 0;
#else #else
if (__builtin_expect(dbg == -1, 0)) { if (0) {
const char* e = getenv("HAKMEM_SS_FREE_DEBUG");
dbg = (e && *e && *e != '0') ? 1 : 0;
}
#endif #endif
if (dbg == 1) {
fprintf(stderr, "[FREE_PATH] meta->used=0 detected: cls=%u ss=%p slab_idx=%d\n", fprintf(stderr, "[FREE_PATH] meta->used=0 detected: cls=%u ss=%p slab_idx=%d\n",
cls, (void*)ss, slab_idx); cls, (void*)ss, slab_idx);
} }
@ -447,15 +427,12 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
tiny_next_write(cls, base, prev); tiny_next_write(cls, base, prev);
meta->freelist = base; meta->freelist = base;
tiny_failfast_log("free_local_legacy", cls, ss, meta, ptr, prev); tiny_failfast_log("free_local_legacy", cls, ss, meta, ptr, prev);
// Priority-2: Use cached ENV (eliminate lazy-init static overhead)
do { do {
static int g_mask_en = -1; #if !HAKMEM_BUILD_RELEASE
#if HAKMEM_BUILD_RELEASE int g_mask_en = (HAK_ENV_TINY_FREELIST_MASK() != 0) ? 1 : 0;
g_mask_en = 0;
#else #else
if (__builtin_expect(g_mask_en == -1, 0)) { int g_mask_en = 0;
const char* e = getenv("HAKMEM_TINY_FREELIST_MASK");
g_mask_en = (e && *e && *e != '0') ? 1 : 0;
}
#endif #endif
if (__builtin_expect(g_mask_en, 0) && prev == NULL) { if (__builtin_expect(g_mask_en, 0) && prev == NULL) {
uint32_t bit = (1u << slab_idx); uint32_t bit = (1u << slab_idx);
@ -472,13 +449,12 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
// 空検出は別途(ホットパス除外) // 空検出は別途(ホットパス除外)
// Phase 12: slab empty → shared pool に返却 // Phase 12: slab empty → shared pool に返却
if (meta->used == 0) { if (meta->used == 0) {
// DEBUG LOGGING // DEBUG LOGGING - Priority-2: Use cached ENV (eliminate lazy-init TLS overhead)
static __thread int dbg = -1; #if !HAKMEM_BUILD_RELEASE
if (__builtin_expect(dbg == -1, 0)) { if (HAK_ENV_SS_FREE_DEBUG()) {
const char* e = getenv("HAKMEM_SS_FREE_DEBUG"); #else
dbg = (e && *e && *e != '0') ? 1 : 0; if (0) {
} #endif
if (dbg == 1) {
fprintf(stderr, "[FREE_PATH] meta->used=0 detected: cls=%u ss=%p slab_idx=%d\n", fprintf(stderr, "[FREE_PATH] meta->used=0 detected: cls=%u ss=%p slab_idx=%d\n",
cls, (void*)ss, slab_idx); cls, (void*)ss, slab_idx);
} }