ENV Cleanup Phase 5: Additional DEBUG guards + doc cleanup

Code changes:
- core/slab_handle.h: Add RELEASE guard for HAKMEM_TINY_FREELIST_MASK
- core/tiny_superslab_free.inc.h: Add guards for HAKMEM_TINY_ROUTE_FREE, HAKMEM_TINY_FREELIST_MASK

Documentation cleanup:
- docs/specs/CONFIGURATION.md: Remove 21 doc-only ENV variables
- docs/specs/ENV_VARS.md: Remove doc-only variables

Testing:
- Build: PASS (305KB binary, unchanged)
- Sanity: PASS (17.22M ops/s average, 3 runs)
- Larson: PASS (52.12M ops/s, 0 crashes)

Impact:
- 2 additional DEBUG ENV variables guarded (no overhead in RELEASE)
- Documentation accuracy improved
- Binary size maintained

🤖 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-11-27 03:55:17 +09:00
parent 43015725af
commit f4978b1529
4 changed files with 20 additions and 84 deletions

View File

@ -260,10 +260,14 @@ static inline int slab_freelist_push(SlabHandle* h, void* ptr) {
// Optional freelist mask update (opt-in via env HAKMEM_TINY_FREELIST_MASK) // Optional freelist mask update (opt-in via env HAKMEM_TINY_FREELIST_MASK)
do { do {
static int g_mask_en = -1; static int g_mask_en = -1;
#if HAKMEM_BUILD_RELEASE
g_mask_en = 0;
#else
if (__builtin_expect(g_mask_en == -1, 0)) { if (__builtin_expect(g_mask_en == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_FREELIST_MASK"); const char* e = getenv("HAKMEM_TINY_FREELIST_MASK");
g_mask_en = (e && *e && *e != '0') ? 1 : 0; g_mask_en = (e && *e && *e != '0') ? 1 : 0;
} }
#endif
if (__builtin_expect(g_mask_en, 0) && prev == NULL && h->ss) { if (__builtin_expect(g_mask_en, 0) && prev == NULL && h->ss) {
uint32_t bit = (1u << h->slab_idx); uint32_t bit = (1u << h->slab_idx);
atomic_fetch_or_explicit(&h->ss->freelist_mask, bit, memory_order_release); atomic_fetch_or_explicit(&h->ss->freelist_mask, bit, memory_order_release);
@ -310,10 +314,14 @@ static inline void* slab_freelist_pop(SlabHandle* h) {
// Optional freelist mask clear when freelist becomes empty // Optional freelist mask clear when freelist becomes empty
do { do {
static int g_mask_en2 = -1; static int g_mask_en2 = -1;
#if HAKMEM_BUILD_RELEASE
g_mask_en2 = 0;
#else
if (__builtin_expect(g_mask_en2 == -1, 0)) { if (__builtin_expect(g_mask_en2 == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_FREELIST_MASK"); const char* e = getenv("HAKMEM_TINY_FREELIST_MASK");
g_mask_en2 = (e && *e && *e != '0') ? 1 : 0; g_mask_en2 = (e && *e && *e != '0') ? 1 : 0;
} }
#endif
if (__builtin_expect(g_mask_en2, 0) && next == NULL && h->ss) { if (__builtin_expect(g_mask_en2, 0) && next == NULL && h->ss) {
uint32_t bit = (1u << h->slab_idx); uint32_t bit = (1u << h->slab_idx);
atomic_fetch_and_explicit(&h->ss->freelist_mask, ~bit, memory_order_release); atomic_fetch_and_explicit(&h->ss->freelist_mask, ~bit, memory_order_release);

View File

@ -249,9 +249,15 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
ROUTE_MARK(20); // mailbox_publish ROUTE_MARK(20); // mailbox_publish
// Free-side route commit (one-shot) // Free-side route commit (one-shot)
do { do {
static int g_route_free = -1; if (__builtin_expect(g_route_free == -1, 0)) { static int g_route_free = -1;
#if HAKMEM_BUILD_RELEASE
g_route_free = 0;
#else
if (__builtin_expect(g_route_free == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_ROUTE_FREE"); const char* e = getenv("HAKMEM_TINY_ROUTE_FREE");
g_route_free = (e && *e && *e != '0') ? 1 : 0; } g_route_free = (e && *e && *e != '0') ? 1 : 0;
}
#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);
} }
@ -439,10 +445,14 @@ static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) {
tiny_failfast_log("free_local_legacy", cls, ss, meta, ptr, prev); tiny_failfast_log("free_local_legacy", cls, ss, meta, ptr, prev);
do { do {
static int g_mask_en = -1; static int g_mask_en = -1;
#if HAKMEM_BUILD_RELEASE
g_mask_en = 0;
#else
if (__builtin_expect(g_mask_en == -1, 0)) { if (__builtin_expect(g_mask_en == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_FREELIST_MASK"); const char* e = getenv("HAKMEM_TINY_FREELIST_MASK");
g_mask_en = (e && *e && *e != '0') ? 1 : 0; g_mask_en = (e && *e && *e != '0') ? 1 : 0;
} }
#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);
atomic_fetch_or_explicit(&ss->freelist_mask, bit, memory_order_release); atomic_fetch_or_explicit(&ss->freelist_mask, bit, memory_order_release);

View File

@ -44,36 +44,6 @@ export HAKMEM_WRAP_TINY=0 HAKMEM_WRAP_POOL=0 HAKMEM_WRAP_MID=0 HAKMEM_WRAP_LARGE
--- ---
## 🐛 Debug & Diagnostics
**Canonical Variables** (After P0.4 - Debug Consolidation):
| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `HAKMEM_DEBUG_LEVEL` | 0-3 | 0 | Verbosity (0=none, 1=errors, 2=info, 3=verbose) |
| `HAKMEM_DEBUG_TINY` | 0, 1 | 0 | Enable TINY allocator debug output |
| `HAKMEM_TRACE_ALLOCATIONS` | 0, 1 | 0 | Trace every alloc/free (expensive!) |
| `HAKMEM_INTEGRITY_CHECKS` | 0, 1 | 1 | Enable integrity validation (canary checks) |
**Examples**:
```bash
# Production (quiet, integrity only)
export HAKMEM_DEBUG_LEVEL=0
export HAKMEM_INTEGRITY_CHECKS=1
# Debug session (verbose + TINY debug + tracing)
export HAKMEM_DEBUG_LEVEL=3
export HAKMEM_DEBUG_TINY=1
export HAKMEM_TRACE_ALLOCATIONS=1
export HAKMEM_INTEGRITY_CHECKS=1
# Performance testing (all checks OFF)
export HAKMEM_DEBUG_LEVEL=0
export HAKMEM_INTEGRITY_CHECKS=0
```
---
## 🏗️ SuperSlab Management ## 🏗️ SuperSlab Management
**Canonical Variables** (After P0.1 - SuperSlab Unification): **Canonical Variables** (After P0.1 - SuperSlab Unification):
@ -114,49 +84,22 @@ Controls adaptive sizing for allocator caches (TLS, SFC, capacity tuning).
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `HAKMEM_ALLOC_LEARN` | 0, 1 | 0 | Enable allocation pattern learning |
| `HAKMEM_ALLOC_LEARN_WINDOW` | 1-1000000 | 10000 | Learning window size (operations) |
| `HAKMEM_ALLOC_LEARN_RATE` | 0.0-1.0 | 0.1 | Learning rate (lower = slower adaptation) |
### Memory Learning ### Memory Learning
Controls THP (Transparent Huge Pages), RSS optimization, and max-size learning. Controls THP (Transparent Huge Pages), RSS optimization, and max-size learning.
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `HAKMEM_MEM_LEARN` | 0, 1 | 0 | Enable memory pattern learning (THP/RSS/WMAX) |
| `HAKMEM_MEM_LEARN_WINDOW` | 1-1000000 | 5000 | Learning window size (operations) |
| `HAKMEM_MEM_LEARN_THRESHOLD` | 0.0-1.0 | 0.8 | Activation threshold (80% confidence) |
### Advanced Overrides ### Advanced Overrides
**For troubleshooting only** - enables legacy advanced knobs that are auto-tuned by default. **For troubleshooting only** - enables legacy advanced knobs that are auto-tuned by default.
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `HAKMEM_LEARN_ADVANCED` | 0, 1 | 0 | Enable advanced override knobs (see DEPRECATED.md) |
**Examples**: **Examples**:
```bash ```bash
# Production (learning disabled, use static tuning) # Production (learning disabled, use static tuning)
export HAKMEM_ALLOC_LEARN=0
export HAKMEM_MEM_LEARN=0
# Adaptive workload (enable both learners)
export HAKMEM_ALLOC_LEARN=1
export HAKMEM_ALLOC_LEARN_WINDOW=20000
export HAKMEM_ALLOC_LEARN_RATE=0.05
export HAKMEM_MEM_LEARN=1
export HAKMEM_MEM_LEARN_WINDOW=10000
export HAKMEM_MEM_LEARN_THRESHOLD=0.75
# Migration troubleshooting (enable advanced overrides)
export HAKMEM_LEARN_ADVANCED=1
export HAKMEM_LEARN_DECAY=0.95 # Override auto-tuned decay
```
**Migration Note**: See [DEPRECATED.md](DEPRECATED.md) for mapping of 18 legacy variables → 6 canonical variables.
---
## 🎯 TINY Allocator (1-2048B) ## 🎯 TINY Allocator (1-2048B)
### TLS Cache Configuration ### TLS Cache Configuration
@ -237,18 +180,10 @@ export HAKMEM_POOL_TLS_ARENA_GROWTH_LEVELS=5 # 4MB→8MB→16MB→32MB
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `HAKMEM_STATS_ENABLE` | 0, 1 | 0 | Enable statistics collection |
| `HAKMEM_STATS_VERBOSE` | 0, 1 | 0 | Verbose stats output |
| `HAKMEM_STATS_INTERVAL_SEC` | 1-3600 | 10 | Stats reporting interval (seconds) |
| `HAKMEM_PROFILE_SYSCALLS` | 0, 1 | 0 | Profile syscall counts (mmap/munmap/madvise) |
**Example**: **Example**:
```bash ```bash
# Enable stats for performance analysis # Enable stats for performance analysis
export HAKMEM_STATS_ENABLE=1
export HAKMEM_STATS_VERBOSE=1
export HAKMEM_STATS_INTERVAL_SEC=5
export HAKMEM_PROFILE_SYSCALLS=1
``` ```
--- ---
@ -259,8 +194,6 @@ export HAKMEM_PROFILE_SYSCALLS=1
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `HAKMEM_EXPERIMENTAL_ADAPTIVE_DRAIN` | 0, 1 | 0 | Adaptive remote free drain threshold |
| `HAKMEM_EXPERIMENTAL_CACHE_TUNING` | 0, 1 | 0 | Runtime cache capacity tuning |
--- ---
@ -272,16 +205,12 @@ export HAKMEM_PROFILE_SYSCALLS=1
export HAKMEM_SUPERSLAB_LAZY=1 export HAKMEM_SUPERSLAB_LAZY=1
export HAKMEM_SUPERSLAB_LRU_CAP=256 export HAKMEM_SUPERSLAB_LRU_CAP=256
export HAKMEM_TINY_P0_ENABLE=1 export HAKMEM_TINY_P0_ENABLE=1
export HAKMEM_INTEGRITY_CHECKS=1
``` ```
### 2. Debug Session ### 2. Debug Session
```bash ```bash
# Verbose logging, tracing, integrity checks # Verbose logging, tracing, integrity checks
export HAKMEM_DEBUG_LEVEL=3
export HAKMEM_DEBUG_TINY=1
export HAKMEM_TRACE_ALLOCATIONS=1 export HAKMEM_TRACE_ALLOCATIONS=1
export HAKMEM_INTEGRITY_CHECKS=1
export HAKMEM_TINY_P0_LOG=1 export HAKMEM_TINY_P0_LOG=1
``` ```
@ -327,13 +256,11 @@ export HAKMEM_POOL_TLS_ARENA_MB_MAX=2
./scripts/validate_config.sh ./scripts/validate_config.sh
# Example output: # Example output:
# [DEPRECATED] HAKMEM_LEARN is deprecated, use HAKMEM_ALLOC_LEARN instead
# Sunset date: 2026-05-26 (6 months from 2025-11-26) # Sunset date: 2026-05-26 (6 months from 2025-11-26)
# See DEPRECATED.md for migration guide # See DEPRECATED.md for migration guide
# #
# [WARN] HAKMEM_TINY_TLS_CAP=2048 is outside typical range (16-1024) # [WARN] HAKMEM_TINY_TLS_CAP=2048 is outside typical range (16-1024)
# #
# [OK] HAKMEM_DEBUG_LEVEL=2
# [OK] HAKMEM_SUPERSLAB_LAZY=1 # [OK] HAKMEM_SUPERSLAB_LAZY=1
``` ```
@ -355,8 +282,6 @@ export HAKMEM_POOL_TLS_ARENA_MB_MAX=2
### Q: What's the difference between ALLOC_LEARN and MEM_LEARN? ### Q: What's the difference between ALLOC_LEARN and MEM_LEARN?
**A**: **A**:
- `HAKMEM_ALLOC_LEARN`: Tunes **allocator behavior** (cache sizes, refill batches) based on allocation patterns
- `HAKMEM_MEM_LEARN`: Tunes **memory management** (THP usage, RSS optimization, max-size detection)
### Q: Should I enable learning in production? ### Q: Should I enable learning in production?
**A**: **Generally NO**. Learning adds overhead (~5-10%) and is best for: **A**: **Generally NO**. Learning adds overhead (~5-10%) and is best for:

View File

@ -276,10 +276,3 @@ LD safety (for apps/LD_PRELOAD runs)
- HAKMEM_TINY_BENCH_MODE=1 - HAKMEM_TINY_BENCH_MODE=1
- ベンチ専用の簡素化採用パスを有効化。per-class 単一点の公開スロットを使用し、superslab_refill のスキャンと多段リング走査を回避。 - ベンチ専用の簡素化採用パスを有効化。per-class 単一点の公開スロットを使用し、superslab_refill のスキャンと多段リング走査を回避。
- OOMガードharvest/trimは保持。A/B用途に限定してください。 - OOMガードharvest/trimは保持。A/B用途に限定してください。
Runner build knobsscripts/run_larson_claude.sh
- HAKMEM_BUILD_3LAYER=1
- `make larson_hakmem_3layer` を用いて 3-layer Tiny をビルドして実行LTO=OFF/O1
- HAKMEM_BUILD_ROUTE=1
- `make larson_hakmem_route` を用いて 3-layer + Route 指紋ビルド時ONでビルドして実行。
- 実行時は `HAKMEM_TINY_TRACE_RING=1 HAKMEM_ROUTE=1` を併用してリングにルートを出力。