2025-11-07 01:27:04 +09:00
|
|
|
// tiny_alloc_fast_sfc.inc.h - Box 5-NEW: Super Front Cache (SFC)
|
|
|
|
|
// Purpose: Ultra-fast TLS cache with 128-256 slots (vs old 16 slots)
|
|
|
|
|
// Performance: 3-4 instruction fast path, 95%+ hit rate, refill -98.5%
|
|
|
|
|
// Box Theory: Clear ownership, same-thread only, A/B testable
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdio.h> // For debug output (getenv, fprintf, stderr)
|
|
|
|
|
#include <stdlib.h> // For getenv
|
|
|
|
|
#include "hakmem_tiny.h"
|
Phase E3-FINAL: Fix Box API offset bugs - ALL classes now use correct offsets
## Root Cause Analysis (GPT5)
**Physical Layout Constraints**:
- Class 0: 8B = [1B header][7B payload] → offset 1 = 9B needed = ❌ IMPOSSIBLE
- Class 1-6: >=16B = [1B header][15B+ payload] → offset 1 = ✅ POSSIBLE
- Class 7: 1KB → offset 0 (compatibility)
**Correct Specification**:
- HAKMEM_TINY_HEADER_CLASSIDX != 0:
- Class 0, 7: next at offset 0 (overwrites header when on freelist)
- Class 1-6: next at offset 1 (after header)
- HAKMEM_TINY_HEADER_CLASSIDX == 0:
- All classes: next at offset 0
**Previous Bug**:
- Attempted "ALL classes offset 1" unification
- Class 0 with offset 1 caused immediate SEGV (9B > 8B block size)
- Mixed 2-arg/3-arg API caused confusion
## Fixes Applied
### 1. Restored 3-Argument Box API (core/box/tiny_next_ptr_box.h)
```c
// Correct signatures
void tiny_next_write(int class_idx, void* base, void* next_value)
void* tiny_next_read(int class_idx, const void* base)
// Correct offset calculation
size_t offset = (class_idx == 0 || class_idx == 7) ? 0 : 1;
```
### 2. Updated 123+ Call Sites Across 34 Files
- hakmem_tiny_hot_pop_v4.inc.h (4 locations)
- hakmem_tiny_fastcache.inc.h (3 locations)
- hakmem_tiny_tls_list.h (12 locations)
- superslab_inline.h (5 locations)
- tiny_fastcache.h (3 locations)
- ptr_trace.h (macro definitions)
- tls_sll_box.h (2 locations)
- + 27 additional files
Pattern: `tiny_next_read(base)` → `tiny_next_read(class_idx, base)`
Pattern: `tiny_next_write(base, next)` → `tiny_next_write(class_idx, base, next)`
### 3. Added Sentinel Detection Guards
- tiny_fast_push(): Block nodes with sentinel in ptr or ptr->next
- tls_list_push(): Block nodes with sentinel in ptr or ptr->next
- Defense-in-depth against remote free sentinel leakage
## Verification (GPT5 Report)
**Test Command**: `./out/release/bench_random_mixed_hakmem --iterations=70000`
**Results**:
- ✅ Main loop completed successfully
- ✅ Drain phase completed successfully
- ✅ NO SEGV (previous crash at iteration 66151 is FIXED)
- ℹ️ Final log: "tiny_alloc(1024) failed" is normal fallback to Mid/ACE layers
**Analysis**:
- Class 0 immediate SEGV: ✅ RESOLVED (correct offset 0 now used)
- 66K iteration crash: ✅ RESOLVED (offset consistency fixed)
- Box API conflicts: ✅ RESOLVED (unified 3-arg API)
## Technical Details
### Offset Logic Justification
```
Class 0: 8B block → next pointer (8B) fits ONLY at offset 0
Class 1: 16B block → next pointer (8B) fits at offset 1 (after 1B header)
Class 2: 32B block → next pointer (8B) fits at offset 1
...
Class 6: 512B block → next pointer (8B) fits at offset 1
Class 7: 1024B block → offset 0 for legacy compatibility
```
### Files Modified (Summary)
- Core API: `box/tiny_next_ptr_box.h`
- Hot paths: `hakmem_tiny_hot_pop*.inc.h`, `tiny_fastcache.h`
- TLS layers: `hakmem_tiny_tls_list.h`, `hakmem_tiny_tls_ops.h`
- SuperSlab: `superslab_inline.h`, `tiny_superslab_*.inc.h`
- Refill: `hakmem_tiny_refill.inc.h`, `tiny_refill_opt.h`
- Free paths: `tiny_free_magazine.inc.h`, `tiny_superslab_free.inc.h`
- Documentation: Multiple Phase E3 reports
## Remaining Work
None for Box API offset bugs - all structural issues resolved.
Future enhancements (non-critical):
- Periodic `grep -R '*(void**)' core/` to detect direct pointer access violations
- Enforce Box API usage via static analysis
- Document offset rationale in architecture docs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 06:50:20 +09:00
|
|
|
#include "box/tiny_next_ptr_box.h" // Phase E1-CORRECT: unified next pointer API
|
2025-11-07 01:27:04 +09:00
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Global Config
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// Default capacities (can be overridden per-class)
|
2025-11-11 21:49:05 +09:00
|
|
|
#define SFC_DEFAULT_CAPACITY 256
|
|
|
|
|
#define SFC_DEFAULT_REFILL_COUNT 128
|
2025-11-07 01:27:04 +09:00
|
|
|
#define SFC_DEFAULT_SPILL_THRESH 90 // Spill when >90% full
|
|
|
|
|
|
|
|
|
|
// Per-class capacity limits
|
|
|
|
|
#define SFC_MIN_CAPACITY 16
|
|
|
|
|
#define SFC_MAX_CAPACITY 256
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - TLS Data Structures
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// TLS arrays (one per class, zero-initialized at thread start)
|
|
|
|
|
extern __thread void* g_sfc_head[TINY_NUM_CLASSES]; // Head of linked list
|
|
|
|
|
extern __thread uint32_t g_sfc_count[TINY_NUM_CLASSES]; // Current count
|
|
|
|
|
extern uint32_t g_sfc_capacity[TINY_NUM_CLASSES]; // Target capacity (shared, read-only)
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Statistics (optional, compile-time gated)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
// Fast path metrics
|
|
|
|
|
uint64_t alloc_hits; // Fast path hits (3-4 inst)
|
|
|
|
|
uint64_t alloc_misses; // Fast path misses → refill
|
|
|
|
|
uint64_t free_hits; // Push success
|
|
|
|
|
uint64_t free_full; // Push failed (full) → spill
|
|
|
|
|
|
|
|
|
|
// Slow path metrics
|
|
|
|
|
uint64_t refill_calls; // Refill invocations
|
|
|
|
|
uint64_t refill_blocks; // Total blocks refilled
|
|
|
|
|
uint64_t spill_calls; // Spill invocations
|
|
|
|
|
uint64_t spill_blocks; // Total blocks spilled
|
|
|
|
|
|
|
|
|
|
// Learning metrics (Phase 3)
|
|
|
|
|
uint64_t alloc_window; // Allocs in current window
|
|
|
|
|
uint64_t miss_window; // Misses in current window
|
|
|
|
|
double miss_rate; // miss_window / alloc_window
|
|
|
|
|
int hotness; // 0=cold, 1=warm, 2=hot, 3=scorching
|
|
|
|
|
|
|
|
|
|
// Adaptive config (Phase 3)
|
|
|
|
|
int adaptive_capacity; // Current capacity (16-256)
|
|
|
|
|
int adaptive_refill; // Current refill count (16-128)
|
|
|
|
|
} sfc_stats_t;
|
|
|
|
|
|
|
|
|
|
extern sfc_stats_t g_sfc_stats[TINY_NUM_CLASSES];
|
|
|
|
|
|
|
|
|
|
#endif // HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Fast Path (3-4 instructions)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// Alloc: Pop from SFC cache (inline for zero-cost)
|
|
|
|
|
// Returns: pointer on success, NULL on miss
|
|
|
|
|
// Contract: Caller owns returned pointer
|
|
|
|
|
// Invariants: count ≥ 0, all pointers belong to correct class
|
|
|
|
|
static inline void* sfc_alloc(int cls) {
|
2025-11-10 18:04:08 +09:00
|
|
|
void* base = g_sfc_head[cls];
|
2025-11-07 01:27:04 +09:00
|
|
|
|
2025-11-10 18:04:08 +09:00
|
|
|
if (__builtin_expect(base != NULL, 1)) {
|
Phase E3-FINAL: Fix Box API offset bugs - ALL classes now use correct offsets
## Root Cause Analysis (GPT5)
**Physical Layout Constraints**:
- Class 0: 8B = [1B header][7B payload] → offset 1 = 9B needed = ❌ IMPOSSIBLE
- Class 1-6: >=16B = [1B header][15B+ payload] → offset 1 = ✅ POSSIBLE
- Class 7: 1KB → offset 0 (compatibility)
**Correct Specification**:
- HAKMEM_TINY_HEADER_CLASSIDX != 0:
- Class 0, 7: next at offset 0 (overwrites header when on freelist)
- Class 1-6: next at offset 1 (after header)
- HAKMEM_TINY_HEADER_CLASSIDX == 0:
- All classes: next at offset 0
**Previous Bug**:
- Attempted "ALL classes offset 1" unification
- Class 0 with offset 1 caused immediate SEGV (9B > 8B block size)
- Mixed 2-arg/3-arg API caused confusion
## Fixes Applied
### 1. Restored 3-Argument Box API (core/box/tiny_next_ptr_box.h)
```c
// Correct signatures
void tiny_next_write(int class_idx, void* base, void* next_value)
void* tiny_next_read(int class_idx, const void* base)
// Correct offset calculation
size_t offset = (class_idx == 0 || class_idx == 7) ? 0 : 1;
```
### 2. Updated 123+ Call Sites Across 34 Files
- hakmem_tiny_hot_pop_v4.inc.h (4 locations)
- hakmem_tiny_fastcache.inc.h (3 locations)
- hakmem_tiny_tls_list.h (12 locations)
- superslab_inline.h (5 locations)
- tiny_fastcache.h (3 locations)
- ptr_trace.h (macro definitions)
- tls_sll_box.h (2 locations)
- + 27 additional files
Pattern: `tiny_next_read(base)` → `tiny_next_read(class_idx, base)`
Pattern: `tiny_next_write(base, next)` → `tiny_next_write(class_idx, base, next)`
### 3. Added Sentinel Detection Guards
- tiny_fast_push(): Block nodes with sentinel in ptr or ptr->next
- tls_list_push(): Block nodes with sentinel in ptr or ptr->next
- Defense-in-depth against remote free sentinel leakage
## Verification (GPT5 Report)
**Test Command**: `./out/release/bench_random_mixed_hakmem --iterations=70000`
**Results**:
- ✅ Main loop completed successfully
- ✅ Drain phase completed successfully
- ✅ NO SEGV (previous crash at iteration 66151 is FIXED)
- ℹ️ Final log: "tiny_alloc(1024) failed" is normal fallback to Mid/ACE layers
**Analysis**:
- Class 0 immediate SEGV: ✅ RESOLVED (correct offset 0 now used)
- 66K iteration crash: ✅ RESOLVED (offset consistency fixed)
- Box API conflicts: ✅ RESOLVED (unified 3-arg API)
## Technical Details
### Offset Logic Justification
```
Class 0: 8B block → next pointer (8B) fits ONLY at offset 0
Class 1: 16B block → next pointer (8B) fits at offset 1 (after 1B header)
Class 2: 32B block → next pointer (8B) fits at offset 1
...
Class 6: 512B block → next pointer (8B) fits at offset 1
Class 7: 1024B block → offset 0 for legacy compatibility
```
### Files Modified (Summary)
- Core API: `box/tiny_next_ptr_box.h`
- Hot paths: `hakmem_tiny_hot_pop*.inc.h`, `tiny_fastcache.h`
- TLS layers: `hakmem_tiny_tls_list.h`, `hakmem_tiny_tls_ops.h`
- SuperSlab: `superslab_inline.h`, `tiny_superslab_*.inc.h`
- Refill: `hakmem_tiny_refill.inc.h`, `tiny_refill_opt.h`
- Free paths: `tiny_free_magazine.inc.h`, `tiny_superslab_free.inc.h`
- Documentation: Multiple Phase E3 reports
## Remaining Work
None for Box API offset bugs - all structural issues resolved.
Future enhancements (non-critical):
- Periodic `grep -R '*(void**)' core/` to detect direct pointer access violations
- Enforce Box API usage via static analysis
- Document offset rationale in architecture docs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 06:50:20 +09:00
|
|
|
// Phase E1-CORRECT: Use Box API for next pointer read
|
|
|
|
|
g_sfc_head[cls] = tiny_next_read(cls, base);
|
2025-11-07 01:27:04 +09:00
|
|
|
g_sfc_count[cls]--; // count--
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
g_sfc_stats[cls].alloc_hits++;
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-11-10 18:04:08 +09:00
|
|
|
return base; // 🚀 SFC HIT! (returns base)
|
2025-11-07 01:27:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
g_sfc_stats[cls].alloc_misses++;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return NULL; // Miss → caller should refill
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Free: Push to SFC cache (inline for zero-cost)
|
|
|
|
|
// Returns: 1 on success (cached), 0 on full (caller should spill)
|
|
|
|
|
// Contract: ptr must belong to cls, same-thread only
|
|
|
|
|
// Invariants: count ≤ capacity, linked list integrity
|
|
|
|
|
static inline int sfc_free_push(int cls, void* ptr) {
|
|
|
|
|
uint32_t cap = g_sfc_capacity[cls];
|
|
|
|
|
uint32_t cnt = g_sfc_count[cls];
|
|
|
|
|
|
2025-11-11 21:49:05 +09:00
|
|
|
#if !HAKMEM_BUILD_RELEASE && defined(HAKMEM_SFC_DEBUG_LOG)
|
|
|
|
|
// Debug logging (compile-time gated; zero cost in release)
|
|
|
|
|
do {
|
2025-11-13 13:32:58 +09:00
|
|
|
static __thread int free_debug_enabled = -1;
|
2025-11-11 21:49:05 +09:00
|
|
|
static __thread int free_debug_count = 0;
|
2025-11-13 13:32:58 +09:00
|
|
|
if (__builtin_expect(free_debug_enabled == -1, 0)) {
|
|
|
|
|
free_debug_enabled = getenv("HAKMEM_SFC_DEBUG") ? 1 : 0;
|
|
|
|
|
}
|
|
|
|
|
if (free_debug_enabled && free_debug_count < 20) {
|
2025-11-11 21:49:05 +09:00
|
|
|
free_debug_count++;
|
|
|
|
|
extern int g_sfc_enabled;
|
|
|
|
|
fprintf(stderr, "[SFC_FREE_PUSH] cls=%d, ptr=%p, cnt=%u, cap=%u, will_succeed=%d, enabled=%d\n",
|
|
|
|
|
cls, ptr, cnt, cap, (cnt < cap), g_sfc_enabled);
|
|
|
|
|
}
|
|
|
|
|
} while(0);
|
|
|
|
|
#endif
|
2025-11-07 01:27:04 +09:00
|
|
|
|
|
|
|
|
if (__builtin_expect(cnt < cap, 1)) {
|
Phase E3-FINAL: Fix Box API offset bugs - ALL classes now use correct offsets
## Root Cause Analysis (GPT5)
**Physical Layout Constraints**:
- Class 0: 8B = [1B header][7B payload] → offset 1 = 9B needed = ❌ IMPOSSIBLE
- Class 1-6: >=16B = [1B header][15B+ payload] → offset 1 = ✅ POSSIBLE
- Class 7: 1KB → offset 0 (compatibility)
**Correct Specification**:
- HAKMEM_TINY_HEADER_CLASSIDX != 0:
- Class 0, 7: next at offset 0 (overwrites header when on freelist)
- Class 1-6: next at offset 1 (after header)
- HAKMEM_TINY_HEADER_CLASSIDX == 0:
- All classes: next at offset 0
**Previous Bug**:
- Attempted "ALL classes offset 1" unification
- Class 0 with offset 1 caused immediate SEGV (9B > 8B block size)
- Mixed 2-arg/3-arg API caused confusion
## Fixes Applied
### 1. Restored 3-Argument Box API (core/box/tiny_next_ptr_box.h)
```c
// Correct signatures
void tiny_next_write(int class_idx, void* base, void* next_value)
void* tiny_next_read(int class_idx, const void* base)
// Correct offset calculation
size_t offset = (class_idx == 0 || class_idx == 7) ? 0 : 1;
```
### 2. Updated 123+ Call Sites Across 34 Files
- hakmem_tiny_hot_pop_v4.inc.h (4 locations)
- hakmem_tiny_fastcache.inc.h (3 locations)
- hakmem_tiny_tls_list.h (12 locations)
- superslab_inline.h (5 locations)
- tiny_fastcache.h (3 locations)
- ptr_trace.h (macro definitions)
- tls_sll_box.h (2 locations)
- + 27 additional files
Pattern: `tiny_next_read(base)` → `tiny_next_read(class_idx, base)`
Pattern: `tiny_next_write(base, next)` → `tiny_next_write(class_idx, base, next)`
### 3. Added Sentinel Detection Guards
- tiny_fast_push(): Block nodes with sentinel in ptr or ptr->next
- tls_list_push(): Block nodes with sentinel in ptr or ptr->next
- Defense-in-depth against remote free sentinel leakage
## Verification (GPT5 Report)
**Test Command**: `./out/release/bench_random_mixed_hakmem --iterations=70000`
**Results**:
- ✅ Main loop completed successfully
- ✅ Drain phase completed successfully
- ✅ NO SEGV (previous crash at iteration 66151 is FIXED)
- ℹ️ Final log: "tiny_alloc(1024) failed" is normal fallback to Mid/ACE layers
**Analysis**:
- Class 0 immediate SEGV: ✅ RESOLVED (correct offset 0 now used)
- 66K iteration crash: ✅ RESOLVED (offset consistency fixed)
- Box API conflicts: ✅ RESOLVED (unified 3-arg API)
## Technical Details
### Offset Logic Justification
```
Class 0: 8B block → next pointer (8B) fits ONLY at offset 0
Class 1: 16B block → next pointer (8B) fits at offset 1 (after 1B header)
Class 2: 32B block → next pointer (8B) fits at offset 1
...
Class 6: 512B block → next pointer (8B) fits at offset 1
Class 7: 1024B block → offset 0 for legacy compatibility
```
### Files Modified (Summary)
- Core API: `box/tiny_next_ptr_box.h`
- Hot paths: `hakmem_tiny_hot_pop*.inc.h`, `tiny_fastcache.h`
- TLS layers: `hakmem_tiny_tls_list.h`, `hakmem_tiny_tls_ops.h`
- SuperSlab: `superslab_inline.h`, `tiny_superslab_*.inc.h`
- Refill: `hakmem_tiny_refill.inc.h`, `tiny_refill_opt.h`
- Free paths: `tiny_free_magazine.inc.h`, `tiny_superslab_free.inc.h`
- Documentation: Multiple Phase E3 reports
## Remaining Work
None for Box API offset bugs - all structural issues resolved.
Future enhancements (non-critical):
- Periodic `grep -R '*(void**)' core/` to detect direct pointer access violations
- Enforce Box API usage via static analysis
- Document offset rationale in architecture docs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 06:50:20 +09:00
|
|
|
// Phase E1-CORRECT: Use Box API for next pointer write
|
|
|
|
|
tiny_next_write(cls, ptr, g_sfc_head[cls]);
|
2025-11-10 18:04:08 +09:00
|
|
|
g_sfc_head[cls] = ptr; // head = base
|
2025-11-07 01:27:04 +09:00
|
|
|
g_sfc_count[cls] = cnt + 1; // count++
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
g_sfc_stats[cls].free_hits++;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 1; // Success
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
g_sfc_stats[cls].free_full++;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 0; // Full → caller should spill
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Public API (slow path, not inline)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// Initialize SFC (called once at startup)
|
|
|
|
|
void sfc_init(void);
|
2025-11-11 21:49:05 +09:00
|
|
|
void sfc_cascade_from_tls_initial(void);
|
2025-11-07 01:27:04 +09:00
|
|
|
|
|
|
|
|
// Shutdown SFC (called at exit, optional)
|
|
|
|
|
void sfc_shutdown(void);
|
|
|
|
|
|
|
|
|
|
// Refill: Batch refill from backend (Magazine/SuperSlab)
|
|
|
|
|
// Returns: number of blocks refilled (0 on failure)
|
|
|
|
|
// Contract: Transfers ownership from backend to SFC
|
|
|
|
|
int sfc_refill(int cls, int target_count);
|
|
|
|
|
|
|
|
|
|
// Spill: Batch spill to backend when cache too full
|
|
|
|
|
// Returns: number of blocks spilled
|
|
|
|
|
// Contract: Transfers ownership from SFC to backend
|
|
|
|
|
int sfc_spill(int cls, int spill_count);
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Configuration (tuning)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
int capacity; // Target capacity (128-256)
|
|
|
|
|
int refill_count; // Batch refill size (64-128)
|
|
|
|
|
int spill_thresh; // Spill when count > capacity * thresh%
|
|
|
|
|
} sfc_config_t;
|
|
|
|
|
|
|
|
|
|
sfc_config_t sfc_get_config(int cls);
|
|
|
|
|
void sfc_set_config(int cls, sfc_config_t cfg);
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Statistics (debugging)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
#if HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
|
|
|
|
|
sfc_stats_t sfc_get_stats(int cls);
|
|
|
|
|
void sfc_reset_stats(int cls);
|
|
|
|
|
void sfc_print_stats(void); // Human-readable dump
|
|
|
|
|
|
|
|
|
|
#endif // HAKMEM_DEBUG_COUNTERS
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Feature Flag (A/B testing)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// Global enable flag (set via ENV: HAKMEM_SFC_ENABLE)
|
|
|
|
|
extern int g_sfc_enabled;
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Box 5-NEW: Super Front Cache - Box Theory Compliance
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
// Invariants (enforced by design):
|
|
|
|
|
// - INVARIANT 1: g_sfc_count[cls] <= g_sfc_capacity[cls] (always)
|
|
|
|
|
// - INVARIANT 2: All pointers in cache belong to correct class (caller responsibility)
|
|
|
|
|
// - INVARIANT 3: SFC contains only same-thread allocations (TLS)
|
|
|
|
|
// - INVARIANT 4: Linked list integrity (*ptr points to valid node or NULL)
|
|
|
|
|
// - INVARIANT 5: g_sfc_count[cls] >= 0 (always)
|
|
|
|
|
|
|
|
|
|
// Ownership Rules:
|
|
|
|
|
// - SFC owns: Cached pointers in g_sfc_head[cls] linked list
|
|
|
|
|
// - Transfer IN: sfc_refill() from Magazine/SuperSlab (batch)
|
|
|
|
|
// - Transfer OUT: sfc_alloc() to application (single)
|
|
|
|
|
// - Return: sfc_free_push() from application (single)
|
|
|
|
|
// - Spill: sfc_spill() to Magazine/SuperSlab (batch)
|
|
|
|
|
|
|
|
|
|
// Boundaries:
|
|
|
|
|
// - Minimal coupling: Reuses existing sll_refill_small_from_ss()
|
|
|
|
|
// - Fallback: Old Box 5 (TLS SLL 16 slots) remains for backward compat
|
|
|
|
|
// - A/B testable: HAKMEM_SFC_ENABLE=0/1 switches between old/new
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// End of tiny_alloc_fast_sfc.inc.h
|
|
|
|
|
// ============================================================================
|