**問題:**
- Larson 4T で 100% SEGV (1T は 2.09M ops/s で完走)
- System/mimalloc は 4T で 33.52M ops/s 正常動作
- SS OFF + Remote OFF でも 4T で SEGV
**根本原因: (Task agent ultrathink 調査結果)**
```
CRASH: mov (%r15),%r13
R15 = 0x6261 ← ASCII "ba" (ゴミ値、未初期化TLS)
```
Worker スレッドの TLS 変数が未初期化:
- `__thread void* g_tls_sll_head[TINY_NUM_CLASSES];` ← 初期化なし
- pthread_create() で生成されたスレッドでゼロ初期化されない
- NULL チェックが通過 (0x6261 != NULL) → dereference → SEGV
**修正内容:**
全 TLS 配列に明示的初期化子 `= {0}` を追加:
1. **core/hakmem_tiny.c:**
- `g_tls_sll_head[TINY_NUM_CLASSES] = {0}`
- `g_tls_sll_count[TINY_NUM_CLASSES] = {0}`
- `g_tls_live_ss[TINY_NUM_CLASSES] = {0}`
- `g_tls_bcur[TINY_NUM_CLASSES] = {0}`
- `g_tls_bend[TINY_NUM_CLASSES] = {0}`
2. **core/tiny_fastcache.c:**
- `g_tiny_fast_cache[TINY_FAST_CLASS_COUNT] = {0}`
- `g_tiny_fast_count[TINY_FAST_CLASS_COUNT] = {0}`
- `g_tiny_fast_free_head[TINY_FAST_CLASS_COUNT] = {0}`
- `g_tiny_fast_free_count[TINY_FAST_CLASS_COUNT] = {0}`
3. **core/hakmem_tiny_magazine.c:**
- `g_tls_mags[TINY_NUM_CLASSES] = {0}`
4. **core/tiny_sticky.c:**
- `g_tls_sticky_ss[TINY_NUM_CLASSES][TINY_STICKY_RING] = {0}`
- `g_tls_sticky_idx[TINY_NUM_CLASSES][TINY_STICKY_RING] = {0}`
- `g_tls_sticky_pos[TINY_NUM_CLASSES] = {0}`
**効果:**
```
Before: 1T: 2.09M ✅ | 4T: SEGV 💀
After: 1T: 2.41M ✅ | 4T: 4.19M ✅ (+15% 1T, SEGV解消)
```
**テスト:**
```bash
# 1 thread: 完走
./larson_hakmem 2 8 128 1024 1 12345 1
→ Throughput = 2,407,597 ops/s ✅
# 4 threads: 完走(以前は SEGV)
./larson_hakmem 2 8 128 1024 1 12345 4
→ Throughput = 4,192,155 ops/s ✅
```
**調査協力:** Task agent (ultrathink mode) による完璧な根本原因特定
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
113 lines
3.6 KiB
C
113 lines
3.6 KiB
C
// hakmem_build_flags.h - Centralized compile-time feature switches
|
|
// Purpose: Define all build-time toggles in one place with safe defaults.
|
|
// Usage: Include from common public headers (e.g., hakmem.h / hakmem_tiny.h).
|
|
|
|
#ifndef HAKMEM_BUILD_FLAGS_H
|
|
#define HAKMEM_BUILD_FLAGS_H
|
|
|
|
// ------------------------------------------------------------
|
|
// Release/debug detection
|
|
// ------------------------------------------------------------
|
|
// HAKMEM_BUILD_RELEASE: 1 in release-like builds, 0 otherwise
|
|
#ifndef HAKMEM_BUILD_RELEASE
|
|
# if defined(NDEBUG)
|
|
# define HAKMEM_BUILD_RELEASE 1
|
|
# else
|
|
# define HAKMEM_BUILD_RELEASE 0
|
|
# endif
|
|
#endif
|
|
|
|
// ------------------------------------------------------------
|
|
// Instrumentation & counters (compile-time)
|
|
// ------------------------------------------------------------
|
|
// Enable lightweight path/debug counters (compiled out when 0)
|
|
#ifndef HAKMEM_DEBUG_COUNTERS
|
|
# define HAKMEM_DEBUG_COUNTERS 1
|
|
#endif
|
|
|
|
// Enable extended memory profiling (compiled out when 0)
|
|
#ifndef HAKMEM_DEBUG_MEMORY
|
|
# define HAKMEM_DEBUG_MEMORY 0
|
|
#endif
|
|
|
|
// Tiny refill optimization helpers (header-only)
|
|
#ifndef HAKMEM_TINY_REFILL_OPT
|
|
# define HAKMEM_TINY_REFILL_OPT 1
|
|
#endif
|
|
|
|
// Batch refill P0 (can be toggled for A/B)
|
|
#ifndef HAKMEM_TINY_P0_BATCH_REFILL
|
|
# define HAKMEM_TINY_P0_BATCH_REFILL 1
|
|
#endif
|
|
|
|
// Box refactor (Phase 6-1.7) — usually injected from build system
|
|
#ifndef HAKMEM_TINY_PHASE6_BOX_REFACTOR
|
|
# define HAKMEM_TINY_PHASE6_BOX_REFACTOR 1
|
|
#endif
|
|
|
|
// ------------------------------------------------------------
|
|
// Tiny front architecture toggles (compile-time defaults)
|
|
// ------------------------------------------------------------
|
|
// New 3-layer Tiny front (A/B via build flag)
|
|
#ifndef HAKMEM_TINY_USE_NEW_3LAYER
|
|
# define HAKMEM_TINY_USE_NEW_3LAYER 0
|
|
#endif
|
|
|
|
// Minimal/strict front variants (bench/debug only)
|
|
#ifndef HAKMEM_TINY_MINIMAL_FRONT
|
|
# define HAKMEM_TINY_MINIMAL_FRONT 0
|
|
#endif
|
|
#ifndef HAKMEM_TINY_STRICT_FRONT
|
|
# define HAKMEM_TINY_STRICT_FRONT 0
|
|
#endif
|
|
|
|
// Route fingerprint (compile-time gate; runtime ENV still required)
|
|
#ifndef HAKMEM_ROUTE
|
|
# define HAKMEM_ROUTE 0
|
|
#endif
|
|
|
|
// Bench-only knobs (default values; can be overridden via build flags)
|
|
#ifndef HAKMEM_TINY_BENCH_REFILL
|
|
# define HAKMEM_TINY_BENCH_REFILL 8
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_REFILL8
|
|
# define HAKMEM_TINY_BENCH_REFILL8 HAKMEM_TINY_BENCH_REFILL
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_REFILL16
|
|
# define HAKMEM_TINY_BENCH_REFILL16 HAKMEM_TINY_BENCH_REFILL
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_REFILL32
|
|
# define HAKMEM_TINY_BENCH_REFILL32 HAKMEM_TINY_BENCH_REFILL
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_REFILL64
|
|
# define HAKMEM_TINY_BENCH_REFILL64 HAKMEM_TINY_BENCH_REFILL
|
|
#endif
|
|
|
|
#ifndef HAKMEM_TINY_BENCH_WARMUP8
|
|
# define HAKMEM_TINY_BENCH_WARMUP8 64
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_WARMUP16
|
|
# define HAKMEM_TINY_BENCH_WARMUP16 96
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_WARMUP32
|
|
# define HAKMEM_TINY_BENCH_WARMUP32 160
|
|
#endif
|
|
#ifndef HAKMEM_TINY_BENCH_WARMUP64
|
|
# define HAKMEM_TINY_BENCH_WARMUP64 192
|
|
#endif
|
|
|
|
// ------------------------------------------------------------
|
|
// Helper enum (for documentation / logging)
|
|
// ------------------------------------------------------------
|
|
typedef enum {
|
|
HAK_FLAG_BUILD_RELEASE = HAKMEM_BUILD_RELEASE,
|
|
HAK_FLAG_DEBUG_COUNTERS = HAKMEM_DEBUG_COUNTERS,
|
|
HAK_FLAG_DEBUG_MEMORY = HAKMEM_DEBUG_MEMORY,
|
|
HAK_FLAG_REFILL_OPT = HAKMEM_TINY_REFILL_OPT,
|
|
HAK_FLAG_P0_BATCH = HAKMEM_TINY_P0_BATCH_REFILL,
|
|
HAK_FLAG_BOX_REFACTOR = HAKMEM_TINY_PHASE6_BOX_REFACTOR,
|
|
HAK_FLAG_NEW_3LAYER = HAKMEM_TINY_USE_NEW_3LAYER,
|
|
} hak_build_flags_t;
|
|
|
|
#endif // HAKMEM_BUILD_FLAGS_H
|