diff --git a/core/box/hak_alloc_api.inc.h b/core/box/hak_alloc_api.inc.h index bde1289a..74acc37e 100644 --- a/core/box/hak_alloc_api.inc.h +++ b/core/box/hak_alloc_api.inc.h @@ -2,6 +2,8 @@ #ifndef HAK_ALLOC_API_INC_H #define HAK_ALLOC_API_INC_H +#include "../hakmem_tiny.h" // For tiny_get_max_size() (Phase 16) + #ifdef HAKMEM_POOL_TLS_PHASE1 #include "../pool_tls.h" #endif @@ -29,7 +31,9 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { uintptr_t site_id = (uintptr_t)site; - if (__builtin_expect(size <= TINY_MAX_SIZE, 1)) { + // Phase 16: Dynamic Tiny max size (ENV: HAKMEM_TINY_MAX_CLASS) + // Default: 1023B (C0-C7), can be reduced to 255B (C0-C5) to delegate 512/1024B to Mid + if (__builtin_expect(size <= tiny_get_max_size(), 1)) { #if HAKMEM_DEBUG_TIMING HKM_TIME_START(t_tiny); #endif @@ -49,10 +53,10 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { if (tiny_ptr) { hkm_ace_track_alloc(); return tiny_ptr; } // PHASE 7 CRITICAL FIX: No malloc fallback for Tiny failures - // If Tiny fails for size <= TINY_MAX_SIZE, let it flow to Mid/ACE layers + // If Tiny fails for size <= tiny_get_max_size(), let it flow to Mid/ACE layers // This prevents mixed HAKMEM/libc allocation bugs #if HAKMEM_TINY_HEADER_CLASSIDX - if (!tiny_ptr && size <= TINY_MAX_SIZE) { + if (!tiny_ptr && size <= tiny_get_max_size()) { #if !HAKMEM_BUILD_RELEASE // Tiny failed - log and continue to Mid/ACE (no early return!) static int log_count = 0; diff --git a/core/hakmem_mid_mt.c b/core/hakmem_mid_mt.c index 032332b3..d688d26b 100644 --- a/core/hakmem_mid_mt.c +++ b/core/hakmem_mid_mt.c @@ -408,8 +408,8 @@ void mid_mt_init(void) { * Thread-safe, lock-free (uses TLS) */ void* mid_mt_alloc(size_t size) { - // Validate size range - if (unlikely(size < MID_MIN_SIZE || size > MID_MAX_SIZE)) { + // Validate size range (Phase 16: dynamic min size based on Tiny's max) + if (unlikely(size < mid_get_min_size() || size > MID_MAX_SIZE)) { return NULL; } diff --git a/core/hakmem_mid_mt.h b/core/hakmem_mid_mt.h index 281d2fa5..e6c0447a 100644 --- a/core/hakmem_mid_mt.h +++ b/core/hakmem_mid_mt.h @@ -35,10 +35,17 @@ extern "C" { #define MID_NUM_CLASSES 3 // Total number of size classes // Phase 13: Close Tiny/Mid gap. -// Tiny now handles up to 1023B (C7 usable size), so Mid must accept -// 1KB-32KB. We keep size classes at 8/16/32KB; sub-8KB sizes use the -// 8KB class with some internal slack. -#define MID_MIN_SIZE (1024) // 1KB (was 8KB) +// Phase 16: Dynamic Mid min size - must start where Tiny ends +// Tiny max size is configurable via HAKMEM_TINY_MAX_CLASS: +// - HAKMEM_TINY_MAX_CLASS=7 (default) → Tiny up to 1023B → Mid starts at 1024B +// - HAKMEM_TINY_MAX_CLASS=5 → Tiny up to 255B → Mid starts at 256B +#include "hakmem_tiny.h" // For tiny_get_max_size() + +static inline size_t mid_get_min_size(void) { + return tiny_get_max_size() + 1; // Mid starts where Tiny ends +} + +#define MID_MIN_SIZE_STATIC (1024) // Static fallback (C7 default) #define MID_MAX_SIZE (32 * 1024) // 32KB #define MID_CHUNK_SIZE (4 * 1024 * 1024) // 4MB chunks (same as mimalloc segments) @@ -125,9 +132,11 @@ extern MidGlobalRegistry g_mid_registry; void mid_mt_init(void); /** - * mid_mt_alloc - Allocate memory from Mid Range pool (8-32KB) + * mid_mt_alloc - Allocate memory from Mid Range pool * - * @param size Allocation size (must be MID_MIN_SIZE ≤ size ≤ MID_MAX_SIZE) + * @param size Allocation size (must be mid_get_min_size() ≤ size ≤ MID_MAX_SIZE) + * Phase 16: Range adjusts dynamically based on Tiny's max size + * Default: 1024B-32KB, can expand to 256B-32KB if Tiny reduced to C0-C5 * @return Allocated pointer (aligned to block_size), or NULL on failure * * Thread-safety: Lock-free (uses TLS) @@ -211,10 +220,12 @@ static inline size_t mid_class_to_size(int class_idx) { * mid_is_in_range - Check if size is in Mid Range pool range * * @param size Allocation size - * @return true if 8KB ≤ size ≤ 32KB + * @return true if (tiny_max+1) ≤ size ≤ 32KB + * + * Phase 16: Dynamic range - adjusts based on Tiny's max size */ static inline bool mid_is_in_range(size_t size) { - return (size >= MID_MIN_SIZE && size <= MID_MAX_SIZE); + return (size >= mid_get_min_size() && size <= MID_MAX_SIZE); } // ============================================================================ diff --git a/core/hakmem_tiny.c b/core/hakmem_tiny.c index f6d083d2..4db9d1b5 100644 --- a/core/hakmem_tiny.c +++ b/core/hakmem_tiny.c @@ -48,6 +48,36 @@ const size_t g_tiny_class_sizes[TINY_NUM_CLASSES] = { 1024 // Class 7: 1024B total = [Header 1B][Data 1023B] }; +// ============================================================================ +// Phase 16: Dynamic Tiny Max Size (ENV: HAKMEM_TINY_MAX_CLASS) +// ============================================================================ + +// Get dynamic max size for Tiny allocator based on ENV configuration +// Default: 1023B (C0-C7), can be reduced to 255B (C0-C5) +size_t tiny_get_max_size(void) { + static int g_max_class = -1; + if (__builtin_expect(g_max_class == -1, 0)) { + const char* env = getenv("HAKMEM_TINY_MAX_CLASS"); + if (env && *env) { + int max_class = atoi(env); + if (max_class >= 0 && max_class < TINY_NUM_CLASSES) { + g_max_class = max_class; + } else { + g_max_class = 7; // Default: all classes (C0-C7) + } + } else { + g_max_class = 7; // Default: all classes + } + } + + // Map class to max usable size (stride - 1) + // C0=8B, C1=16B, C2=32B, C3=64B, C4=128B, C5=256B, C6=512B, C7=1024B + static const size_t class_to_max_size[TINY_NUM_CLASSES] = { + 7, 15, 31, 63, 127, 255, 511, 1023 + }; + return class_to_max_size[g_max_class]; +} + // ============================================================================ // PRIORITY 1-4: Integrity Check Counters // ============================================================================ diff --git a/core/hakmem_tiny.h b/core/hakmem_tiny.h index f9be4351..2ed8ec7b 100644 --- a/core/hakmem_tiny.h +++ b/core/hakmem_tiny.h @@ -25,7 +25,15 @@ int hak_is_initializing(void); #define TINY_SLAB_SIZE (64 * 1024) // 64KB per slab // Phase E1-CORRECT: All Tiny classes use a 1-byte header. // C7 stride=1024B → usable 1023B (1024-1). 1024B は Mid allocator に委譲する。 -#define TINY_MAX_SIZE 1023 // Tiny handles up to 1023B (C7 usable size) +#define TINY_MAX_SIZE 1023 // Tiny handles up to 1023B (C7 usable size) - default + +// Phase 16: Dynamic Tiny max size control (ENV: HAKMEM_TINY_MAX_CLASS) +// Strategy: Reduce Tiny coverage to ~256B, delegate 512/1024B to Mid +// ENV values: +// HAKMEM_TINY_MAX_CLASS=5 → Tiny handles up to 255B (C0-C5) +// HAKMEM_TINY_MAX_CLASS=7 → Tiny handles up to 1023B (C0-C7, default) +// Forward declaration (implementation in hakmem_tiny.c) +size_t tiny_get_max_size(void); // ============================================================================ // Size Classes