Files
hakmem/core/hakmem_whale.c
Moe Charm (CI) 52386401b3 Debug Counters Implementation - Clean History
Major Features:
- Debug counter infrastructure for Refill Stage tracking
- Free Pipeline counters (ss_local, ss_remote, tls_sll)
- Diagnostic counters for early return analysis
- Unified larson.sh benchmark runner with profiles
- Phase 6-3 regression analysis documentation

Bug Fixes:
- Fix SuperSlab disabled by default (HAKMEM_TINY_USE_SUPERSLAB)
- Fix profile variable naming consistency
- Add .gitignore patterns for large files

Performance:
- Phase 6-3: 4.79 M ops/s (has OOM risk)
- With SuperSlab: 3.13 M ops/s (+19% improvement)

This is a clean repository without large log files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 12:31:14 +09:00

161 lines
4.6 KiB
C

// hakmem_whale.c - Whale Fast-Path Implementation
//
// License: MIT
// Date: 2025-10-21
#include "hakmem_whale.h"
#include "hakmem_sys.h"
#include "hakmem_debug.h"
#include "hakmem_internal.h" // Phase 6.15 P0.1: For HAKMEM_LOG macro
#include <stdio.h>
#include <string.h>
// ============================================================================
// Internal State (FIFO Ring Buffer)
// ============================================================================
typedef struct {
void* ptr; // Block pointer
size_t size; // Block size
} WhaleSlot;
static WhaleSlot g_ring[WHALE_RING_CAPACITY];
static int g_head = 0; // Next slot to read (FIFO output)
static int g_tail = 0; // Next slot to write (FIFO input)
static int g_count = 0; // Current number of cached blocks
// Statistics
static uint64_t g_hits = 0;
static uint64_t g_misses = 0;
static uint64_t g_puts = 0;
static uint64_t g_evictions = 0;
static int g_initialized = 0;
// ============================================================================
// Public API Implementation
// ============================================================================
void hkm_whale_init(void) {
if (g_initialized) return;
memset(g_ring, 0, sizeof(g_ring));
g_head = 0;
g_tail = 0;
g_count = 0;
g_hits = 0;
g_misses = 0;
g_puts = 0;
g_evictions = 0;
g_initialized = 1;
HAKMEM_LOG("[Whale] Initialized (capacity=%d, threshold=%zu MB)\n",
WHALE_RING_CAPACITY, WHALE_MIN_SIZE / (1024 * 1024));
}
void hkm_whale_shutdown(void) {
if (!g_initialized) return;
// Free all cached blocks
for (int i = 0; i < g_count; i++) {
int idx = (g_head + i) % WHALE_RING_CAPACITY;
if (g_ring[idx].ptr) {
hkm_sys_munmap(g_ring[idx].ptr, g_ring[idx].size);
}
}
g_initialized = 0;
}
void* hkm_whale_get(size_t size) {
if (!g_initialized) hkm_whale_init();
if (size < WHALE_MIN_SIZE) return NULL; // Not a whale
HKM_TIME_START(t0);
// FIFO: check if we have any cached blocks
if (g_count == 0) {
HKM_TIME_END(HKM_CAT_WHALE_GET, t0);
g_misses++;
return NULL; // Cache miss
}
// Get oldest block (FIFO head)
WhaleSlot* slot = &g_ring[g_head];
void* ptr = slot->ptr;
size_t cached_size = slot->size;
// Check if size matches (exact match only for now)
if (cached_size < size) {
HKM_TIME_END(HKM_CAT_WHALE_GET, t0);
g_misses++;
return NULL; // Size mismatch
}
// Cache hit! Remove from ring
slot->ptr = NULL;
slot->size = 0;
g_head = (g_head + 1) % WHALE_RING_CAPACITY;
g_count--;
HKM_TIME_END(HKM_CAT_WHALE_GET, t0);
g_hits++;
return ptr;
}
int hkm_whale_put(void* ptr, size_t size) {
if (!g_initialized) hkm_whale_init();
if (!ptr) return 1; // Invalid pointer
if (size < WHALE_MIN_SIZE) return 1; // Not a whale
HKM_TIME_START(t0);
g_puts++;
// Check if cache is full
if (g_count >= WHALE_RING_CAPACITY) {
// Phase 6.11.2: Region Cache (Keep-Map Reuse)
// Evict oldest block with MADV_DONTNEED instead of munmap
// - Releases physical pages (RSS reduction)
// - Keeps VMA mapped (faster than munmap + mmap)
// - OS can reuse VMA for next mmap
WhaleSlot* evict_slot = &g_ring[g_head];
if (evict_slot->ptr) {
hkm_sys_madvise_dontneed(evict_slot->ptr, evict_slot->size);
g_evictions++;
}
g_head = (g_head + 1) % WHALE_RING_CAPACITY;
g_count--;
}
// Add new block to tail
WhaleSlot* slot = &g_ring[g_tail];
slot->ptr = ptr;
slot->size = size;
g_tail = (g_tail + 1) % WHALE_RING_CAPACITY;
g_count++;
HKM_TIME_END(HKM_CAT_WHALE_PUT, t0);
return 0; // Successfully cached
}
void hkm_whale_dump_stats(void) {
if (!g_initialized) return;
fprintf(stderr, "\n========================================\n");
fprintf(stderr, "Whale Fast-Path Statistics\n");
fprintf(stderr, "========================================\n");
fprintf(stderr, "Hits: %lu\n", (unsigned long)g_hits);
fprintf(stderr, "Misses: %lu\n", (unsigned long)g_misses);
fprintf(stderr, "Puts: %lu\n", (unsigned long)g_puts);
fprintf(stderr, "Evictions: %lu\n", (unsigned long)g_evictions);
uint64_t total_gets = g_hits + g_misses;
double hit_rate = total_gets > 0 ? (double)g_hits / total_gets * 100.0 : 0.0;
fprintf(stderr, "Hit Rate: %.1f%%\n", hit_rate);
fprintf(stderr, "Cached: %d / %d slots\n", g_count, WHALE_RING_CAPACITY);
fprintf(stderr, "========================================\n");
}