Files
hakmem/archive/engines/hakx/hakx_api_stub.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

107 lines
3.3 KiB
C

#include <stdlib.h>
#include <string.h>
#include <hakx/hakx_api.h>
#include "hakmem.h"
#include "hakx_front_tiny.h"
#include "hakx_l25_tuner.h"
// Optional mimalloc backend (weak; library may be absent at link/runtime)
void* mi_malloc(size_t size) __attribute__((weak));
void mi_free(void* p) __attribute__((weak));
void* mi_realloc(void* p, size_t newsize) __attribute__((weak));
void* mi_calloc(size_t count, size_t size) __attribute__((weak));
// Phase A: HAKX uses selectable backend (env HAKX_BACKEND=hakmem|mi|sys; default=hakmem).
// Front/Back specialization will be layered later.
static enum { HAKX_B_HAKMEM=0, HAKX_B_MI=1, HAKX_B_SYS=2 } g_hakx_backend = HAKX_B_HAKMEM;
static int g_hakx_env_parsed = 0;
static inline void hakx_parse_backend_once(void) {
if (g_hakx_env_parsed) return;
const char* s = getenv("HAKX_BACKEND");
if (s) {
if (strcmp(s, "mi") == 0) g_hakx_backend = HAKX_B_MI;
else if (strcmp(s, "sys") == 0) g_hakx_backend = HAKX_B_SYS;
else g_hakx_backend = HAKX_B_HAKMEM;
}
const char* tuner = getenv("HAKX_L25_TUNER");
if (tuner && atoi(tuner) != 0) {
hakx_l25_tuner_start();
}
g_hakx_env_parsed = 1;
}
void* hakx_malloc(size_t size) {
hakx_parse_backend_once();
switch (g_hakx_backend) {
case HAKX_B_MI: return mi_malloc ? mi_malloc(size) : malloc(size);
case HAKX_B_SYS: return malloc(size);
default: {
if (hakx_tiny_can_handle(size)) {
void* p = hakx_tiny_alloc(size);
if (p) return p;
// Tiny miss: fall through
}
return hak_alloc_at(size, HAK_CALLSITE());
}
}
}
void hakx_free(void* ptr) {
hakx_parse_backend_once();
if (!ptr) return;
switch (g_hakx_backend) {
case HAKX_B_MI: if (mi_free) mi_free(ptr); else free(ptr); break;
case HAKX_B_SYS: free(ptr); break;
default:
if (hakx_tiny_maybe_free(ptr)) break;
hak_free_at(ptr, 0, HAK_CALLSITE());
break;
}
}
void* hakx_realloc(void* ptr, size_t new_size) {
if (!ptr) return hakx_malloc(new_size);
if (new_size == 0) { hakx_free(ptr); return NULL; }
hakx_parse_backend_once();
switch (g_hakx_backend) {
case HAKX_B_MI:
return mi_realloc ? mi_realloc(ptr, new_size) : realloc(ptr, new_size);
case HAKX_B_SYS:
return realloc(ptr, new_size);
default: {
void* np = hak_alloc_at(new_size, HAK_CALLSITE());
if (!np) return NULL;
memcpy(np, ptr, new_size);
hak_free_at(ptr, 0, HAK_CALLSITE());
return np;
}
}
}
void* hakx_calloc(size_t n, size_t size) {
size_t total;
if (__builtin_mul_overflow(n, size, &total)) return NULL;
hakx_parse_backend_once();
switch (g_hakx_backend) {
case HAKX_B_MI: return mi_calloc ? mi_calloc(n, size) : calloc(n, size);
case HAKX_B_SYS: return calloc(n, size);
default: {
void* p = hak_alloc_at(total, HAK_CALLSITE());
if (p) memset(p, 0, total);
return p;
}
}
}
size_t hakx_usable_size(void* ptr) {
(void)ptr;
// Not exposed in public HAKMEM header; return 0 for now.
return 0;
}
void hakx_trim(void) {
// Future: call tiny/SS trim once exported; currently no-op
}