diff --git a/Makefile b/Makefile index d709852d..827c0814 100644 --- a/Makefile +++ b/Makefile @@ -219,12 +219,12 @@ LDFLAGS += $(EXTRA_LDFLAGS) # Targets TARGET = test_hakmem -OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o superslab_allocate.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o superslab_head.o hakmem_smallmid.o hakmem_smallmid_superslab.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o test_hakmem.o +OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o hakmem_smallmid_superslab.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o test_hakmem.o OBJS = $(OBJS_BASE) # Shared library SHARED_LIB = libhakmem.so -SHARED_OBJS = hakmem_shared.o hakmem_config_shared.o hakmem_tiny_config_shared.o hakmem_ucb1_shared.o hakmem_bigcache_shared.o hakmem_pool_shared.o hakmem_l25_pool_shared.o hakmem_site_rules_shared.o hakmem_tiny_shared.o superslab_allocate_shared.o superslab_stats_shared.o superslab_cache_shared.o superslab_ace_shared.o superslab_slab_shared.o superslab_backend_shared.o superslab_head_shared.o hakmem_smallmid_shared.o hakmem_smallmid_superslab_shared.o core/box/superslab_expansion_box_shared.o core/box/integrity_box_shared.o core/box/mailbox_box_shared.o core/box/front_gate_box_shared.o core/box/front_gate_classifier_shared.o core/box/free_publish_box_shared.o core/box/capacity_box_shared.o core/box/carve_push_box_shared.o core/box/prewarm_box_shared.o core/box/ss_hot_prewarm_box_shared.o core/box/front_metrics_box_shared.o core/box/bench_fast_box_shared.o core/box/ss_addr_map_box_shared.o core/box/slab_recycling_box_shared.o core/box/pagefault_telemetry_box_shared.o core/box/tiny_sizeclass_hist_box_shared.o core/box/tiny_env_box_shared.o core/box/wrapper_env_box_shared.o core/page_arena_shared.o core/front/tiny_unified_cache_shared.o core/tiny_alloc_fast_push_shared.o core/link_stubs_shared.o core/tiny_failfast_shared.o tiny_sticky_shared.o tiny_remote_shared.o tiny_publish_shared.o tiny_debug_ring_shared.o hakmem_tiny_magazine_shared.o hakmem_tiny_stats_shared.o hakmem_tiny_sfc_shared.o hakmem_tiny_query_shared.o hakmem_tiny_rss_shared.o hakmem_tiny_registry_shared.o hakmem_tiny_remote_target_shared.o hakmem_tiny_bg_spill_shared.o tiny_adaptive_sizing_shared.o hakmem_super_registry_shared.o hakmem_shared_pool_shared.o hakmem_shared_pool_acquire_shared.o hakmem_shared_pool_release_shared.o hakmem_elo_shared.o hakmem_batch_shared.o hakmem_p2_shared.o hakmem_sizeclass_dist_shared.o hakmem_evo_shared.o hakmem_debug_shared.o hakmem_sys_shared.o hakmem_whale_shared.o hakmem_policy_shared.o hakmem_ace_shared.o hakmem_ace_stats_shared.o hakmem_ace_controller_shared.o hakmem_ace_metrics_shared.o hakmem_ace_ucb1_shared.o hakmem_prof_shared.o hakmem_learner_shared.o hakmem_size_hist_shared.o hakmem_learn_log_shared.o hakmem_syscall_shared.o tiny_fastcache_shared.o +SHARED_OBJS = hakmem_shared.o hakmem_config_shared.o hakmem_tiny_config_shared.o hakmem_ucb1_shared.o hakmem_bigcache_shared.o hakmem_pool_shared.o hakmem_l25_pool_shared.o hakmem_site_rules_shared.o hakmem_tiny_shared.o core/box/ss_allocation_box_shared.o superslab_stats_shared.o superslab_cache_shared.o superslab_ace_shared.o superslab_slab_shared.o superslab_backend_shared.o core/superslab_head_stub_shared.o hakmem_smallmid_shared.o hakmem_smallmid_superslab_shared.o core/box/superslab_expansion_box_shared.o core/box/integrity_box_shared.o core/box/mailbox_box_shared.o core/box/front_gate_box_shared.o core/box/front_gate_classifier_shared.o core/box/free_publish_box_shared.o core/box/capacity_box_shared.o core/box/carve_push_box_shared.o core/box/prewarm_box_shared.o core/box/ss_hot_prewarm_box_shared.o core/box/front_metrics_box_shared.o core/box/bench_fast_box_shared.o core/box/ss_addr_map_box_shared.o core/box/slab_recycling_box_shared.o core/box/pagefault_telemetry_box_shared.o core/box/tiny_sizeclass_hist_box_shared.o core/box/tiny_env_box_shared.o core/box/wrapper_env_box_shared.o core/page_arena_shared.o core/front/tiny_unified_cache_shared.o core/tiny_alloc_fast_push_shared.o core/link_stubs_shared.o core/tiny_failfast_shared.o tiny_sticky_shared.o tiny_remote_shared.o tiny_publish_shared.o tiny_debug_ring_shared.o hakmem_tiny_magazine_shared.o hakmem_tiny_stats_shared.o hakmem_tiny_sfc_shared.o hakmem_tiny_query_shared.o hakmem_tiny_rss_shared.o hakmem_tiny_registry_shared.o hakmem_tiny_remote_target_shared.o hakmem_tiny_bg_spill_shared.o tiny_adaptive_sizing_shared.o hakmem_super_registry_shared.o hakmem_shared_pool_shared.o hakmem_shared_pool_acquire_shared.o hakmem_shared_pool_release_shared.o hakmem_elo_shared.o hakmem_batch_shared.o hakmem_p2_shared.o hakmem_sizeclass_dist_shared.o hakmem_evo_shared.o hakmem_debug_shared.o hakmem_sys_shared.o hakmem_whale_shared.o hakmem_policy_shared.o hakmem_ace_shared.o hakmem_ace_stats_shared.o hakmem_ace_controller_shared.o hakmem_ace_metrics_shared.o hakmem_ace_ucb1_shared.o hakmem_prof_shared.o hakmem_learner_shared.o hakmem_size_hist_shared.o hakmem_learn_log_shared.o hakmem_syscall_shared.o tiny_fastcache_shared.o # Pool TLS Phase 1 (enable with POOL_TLS_PHASE1=1) ifeq ($(POOL_TLS_PHASE1),1) @@ -251,7 +251,7 @@ endif # Benchmark targets BENCH_HAKMEM = bench_allocators_hakmem BENCH_SYSTEM = bench_allocators_system -BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o superslab_allocate.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o superslab_head.o hakmem_smallmid.o hakmem_smallmid_superslab.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o bench_allocators_hakmem.o +BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o hakmem_smallmid_superslab.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o bench_allocators_hakmem.o BENCH_HAKMEM_OBJS = $(BENCH_HAKMEM_OBJS_BASE) ifeq ($(POOL_TLS_PHASE1),1) BENCH_HAKMEM_OBJS += pool_tls.o pool_refill.o pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o @@ -428,7 +428,7 @@ test-box-refactor: box-refactor ./larson_hakmem 10 8 128 1024 1 12345 4 # Phase 4: Tiny Pool benchmarks (properly linked with hakmem) -TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o superslab_allocate.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o superslab_head.o hakmem_smallmid.o hakmem_smallmid_superslab.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/tiny_sizeclass_hist_box.o core/box/pagefault_telemetry_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o +TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o hakmem_smallmid_superslab.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/tiny_sizeclass_hist_box.o core/box/pagefault_telemetry_box.o core/box/tiny_env_box.o core/box/wrapper_env_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/link_stubs.o core/tiny_failfast.o TINY_BENCH_OBJS = $(TINY_BENCH_OBJS_BASE) ifeq ($(POOL_TLS_PHASE1),1) TINY_BENCH_OBJS += pool_tls.o pool_refill.o core/pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o diff --git a/core/hakmem_tiny_legacy_slow_box.inc b/archive/hakmem_tiny_legacy_slow_box.inc similarity index 93% rename from core/hakmem_tiny_legacy_slow_box.inc rename to archive/hakmem_tiny_legacy_slow_box.inc index af9b6ffb..84c3ebbe 100644 --- a/core/hakmem_tiny_legacy_slow_box.inc +++ b/archive/hakmem_tiny_legacy_slow_box.inc @@ -1,3 +1,7 @@ +// Archived legacy slow allocation path for Tiny pool. +// Not compiled by default; kept for reference / A/B rollback. +// Source moved from core/hakmem_tiny_legacy_slow_box.inc after Box refactor cleanup (2025-12-04). + static __attribute__((cold, noinline, unused)) void* tiny_slow_alloc_fast(int class_idx) { int tls_enabled = g_tls_list_enable; TinyTLSList* tls = &g_tls_lists[class_idx]; @@ -94,3 +98,4 @@ static __attribute__((cold, noinline, unused)) void* tiny_slow_alloc_fast(int cl pthread_mutex_unlock(lock); return ret; } + diff --git a/core/superslab_allocate.c b/archive/superslab_allocate_legacy.c similarity index 97% rename from core/superslab_allocate.c rename to archive/superslab_allocate_legacy.c index 4bd0508d..492d74aa 100644 --- a/core/superslab_allocate.c +++ b/archive/superslab_allocate_legacy.c @@ -1,13 +1,12 @@ -// superslab_allocate.c - SuperSlab allocation and deallocation -// Purpose: Main allocation/free entry points for SuperSlabs -// License: MIT -// Date: 2025-11-28 +// Archived legacy front for SuperSlab allocation/deallocation. +// Not compiled by default; kept for reference / A/B rollback. +// Source moved from core/superslab_allocate.c after Box 化完了 (2025-12-04). -#include "hakmem_tiny_superslab_internal.h" -#include "box/ss_addr_map_box.h" +#include "../core/hakmem_tiny_superslab_internal.h" +#include "../core/box/ss_addr_map_box.h" // ============================================================================ -// SuperSlab Allocation (2MB aligned) +// SuperSlab Allocation (2MB aligned) - Legacy Front // ============================================================================ SuperSlab* superslab_allocate(uint8_t size_class) { @@ -248,7 +247,7 @@ SuperSlab* superslab_allocate(uint8_t size_class) { } // ============================================================================ -// SuperSlab Deallocation +// SuperSlab Deallocation - Legacy Front // ============================================================================ void superslab_free(SuperSlab* ss) { @@ -352,3 +351,4 @@ void superslab_free(SuperSlab* ss) { (unsigned long long)g_superslabs_freed); #endif } + diff --git a/core/superslab_head.c b/archive/superslab_head_legacy.c similarity index 83% rename from core/superslab_head.c rename to archive/superslab_head_legacy.c index ca785391..aba35683 100644 --- a/core/superslab_head.c +++ b/archive/superslab_head_legacy.c @@ -1,9 +1,8 @@ -// superslab_head.c - SuperSlabHead management for dynamic expansion -// Purpose: Per-class chunk lists and expansion logic -// License: MIT -// Date: 2025-11-28 +// Archived legacy SuperSlabHead implementation. +// Not compiled by default; kept for reference / A/B rollback. +// Source moved from core/superslab_head.c after shared-pool backend migration. -#include "hakmem_tiny_superslab_internal.h" +#include "../core/hakmem_tiny_superslab_internal.h" // ============================================================================ // Phase 2a: Dynamic Expansion - Global per-class SuperSlabHeads @@ -38,13 +37,8 @@ SuperSlabHead* init_superslab_head(int class_idx) { pthread_mutex_init(&head->expansion_lock, NULL); // Allocate initial chunk(s) - // Hot classes (1, 4, 6) get 2 initial chunks to reduce contention int initial_chunks = 1; - // Phase 2a: Start with 1 chunk for all classes (expansion will handle growth) - // This reduces startup memory overhead while still allowing unlimited growth - initial_chunks = 1; - for (int i = 0; i < initial_chunks; i++) { if (expand_superslab_head(head) < 0) { extern __thread int g_hakmem_lock_depth; @@ -96,10 +90,8 @@ int expand_superslab_head(SuperSlabHead* head) { return -1; // True OOM (system out of memory) } - // CRITICAL FIX: Initialize slab 0 so bitmap != 0x00000000 - // Phase 2a chunks must have at least one usable slab after allocation + // Initialize slab 0 so bitmap != 0x00000000 size_t block_size = g_tiny_class_sizes[head->class_idx]; - // Use pthread_self() directly since tiny_self_u32() is static inline in hakmem_tiny.c uint32_t owner_tid = (uint32_t)(uintptr_t)pthread_self(); superslab_init_slab(new_chunk, 0, block_size, owner_tid); @@ -111,21 +103,17 @@ int expand_superslab_head(SuperSlabHead* head) { pthread_mutex_lock(&head->expansion_lock); if (head->current_chunk) { - // Find the tail of the list (optimization: could cache tail pointer) SuperSlab* tail = head->current_chunk; while (tail->next_chunk) { tail = tail->next_chunk; } tail->next_chunk = new_chunk; } else { - // First chunk head->first_chunk = new_chunk; } - // Update current chunk to new chunk (for fast allocation) head->current_chunk = new_chunk; - // Increment total chunks atomically size_t old_count = atomic_fetch_add_explicit(&head->total_chunks, 1, memory_order_relaxed); size_t new_count = old_count + 1; @@ -155,24 +143,20 @@ SuperSlab* find_chunk_for_ptr(void* ptr, int class_idx) { uintptr_t ptr_addr = (uintptr_t)ptr; - // Walk the chunk list SuperSlab* chunk = head->first_chunk; while (chunk) { - // Check if ptr is within this chunk's memory range - // Each chunk is aligned to SUPERSLAB_SIZE (1MB or 2MB) uintptr_t chunk_start = (uintptr_t)chunk; - size_t chunk_size = (size_t)1 << chunk->lg_size; // Use actual chunk size + size_t chunk_size = (size_t)1 << chunk->lg_size; uintptr_t chunk_end = chunk_start + chunk_size; if (ptr_addr >= chunk_start && ptr_addr < chunk_end) { - // Found the chunk return chunk; } chunk = chunk->next_chunk; } - return NULL; // Not found in any chunk + return NULL; } // Remove SuperSlab from Legacy Backend list (for safe deallocation) @@ -208,3 +192,4 @@ void remove_superslab_from_legacy_head(SuperSlab* ss) { pthread_mutex_unlock(&head->expansion_lock); } } + diff --git a/core/box/front_gate_classifier.d b/core/box/front_gate_classifier.d index d249c6bf..a5d92954 100644 --- a/core/box/front_gate_classifier.d +++ b/core/box/front_gate_classifier.d @@ -19,8 +19,7 @@ core/box/front_gate_classifier.o: core/box/front_gate_classifier.c \ core/box/../hakmem_build_flags.h core/box/../hakmem_internal.h \ core/box/../hakmem.h core/box/../hakmem_config.h \ core/box/../hakmem_features.h core/box/../hakmem_sys.h \ - core/box/../hakmem_whale.h core/box/../hakmem_tiny_config.h \ - core/box/../pool_tls_registry.h + core/box/../hakmem_whale.h core/box/../hakmem_tiny_config.h core/box/front_gate_classifier.h: core/box/../tiny_region_id.h: core/box/../hakmem_build_flags.h: @@ -55,4 +54,3 @@ core/box/../hakmem_features.h: core/box/../hakmem_sys.h: core/box/../hakmem_whale.h: core/box/../hakmem_tiny_config.h: -core/box/../pool_tls_registry.h: diff --git a/core/box/hak_alloc_api.inc.h b/core/box/hak_alloc_api.inc.h index 8711f3a7..ff73790c 100644 --- a/core/box/hak_alloc_api.inc.h +++ b/core/box/hak_alloc_api.inc.h @@ -75,8 +75,6 @@ inline void* hak_alloc_at(size_t size, hak_callsite_t site) { void* tiny_ptr = NULL; #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR tiny_ptr = hak_tiny_alloc_fast_wrapper(size); -#elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) - tiny_ptr = hak_tiny_alloc_ultra_simple(size); #elif defined(HAKMEM_TINY_PHASE6_METADATA) tiny_ptr = hak_tiny_alloc_metadata(size); #else diff --git a/core/box/hak_lane_classify.inc.h b/core/box/hak_lane_classify.inc.h index 69e36b8c..95a30d02 100644 --- a/core/box/hak_lane_classify.inc.h +++ b/core/box/hak_lane_classify.inc.h @@ -201,6 +201,8 @@ static inline hak_lane_t hak_classify_size(size_t size) { #if !defined(HAKMEM_BUILD_RELEASE) || !HAKMEM_BUILD_RELEASE +#include + /** * hak_lane_name - Get human-readable lane name */ diff --git a/core/box/ss_allocation_box.c b/core/box/ss_allocation_box.c index aba4fe33..dace4c33 100644 --- a/core/box/ss_allocation_box.c +++ b/core/box/ss_allocation_box.c @@ -1,19 +1,15 @@ // Box: Core Allocation -// Purpose: SuperSlab allocation/deallocation and slab initialization +// Purpose: SuperSlab allocation/deallocation (Box化フロント) #include "ss_allocation_box.h" -#include "ss_slab_meta_box.h" // Phase 3d-A: SlabMeta Box boundary #include "ss_os_acquire_box.h" #include "ss_cache_box.h" #include "ss_stats_box.h" #include "ss_ace_box.h" -#include "ss_slab_management_box.h" #include "hakmem_super_registry.h" #include "ss_addr_map_box.h" #include "hakmem_tiny_config.h" #include "hakmem_policy.h" // Phase E3-1: Access FrozenPolicy for never-free policy -#include "tiny_region_id.h" -#include "box/tiny_next_ptr_box.h" #include #include #include @@ -28,51 +24,8 @@ extern uint64_t g_bytes_allocated; // g_ss_force_lg is defined in ss_ace_box.c but needs external linkage extern int g_ss_force_lg; -// g_ss_populate_once controls MAP_POPULATE flag -static _Atomic int g_ss_populate_once = 0; - -// ============================================================================ -// Remote Drain Helper -// ============================================================================ - -// Drain remote MPSC stack into freelist (ownership already verified by caller) -void _ss_remote_drain_to_freelist_unsafe(SuperSlab* ss, int slab_idx, TinySlabMeta* meta) -{ - if (!ss || slab_idx < 0 || slab_idx >= ss_slabs_capacity(ss) || !meta) return; - - // Atomically take the whole remote list - uintptr_t head = atomic_exchange_explicit(&ss->remote_heads[slab_idx], 0, - memory_order_acq_rel); - if (head == 0) return; - - // Convert remote stack (offset 0 next) into freelist encoding via Box API - // and splice in front of current freelist preserving relative order. - void* prev = meta->freelist; - int cls = (int)meta->class_idx; - uintptr_t cur = head; - while (cur != 0) { - uintptr_t next = *(uintptr_t*)cur; // remote-next stored at offset 0 - // Restore header for header-classes (class 1-6) which were clobbered by remote push -#if HAKMEM_TINY_HEADER_CLASSIDX - if (cls != 0 && cls != 7) { - uint8_t expected = (uint8_t)(HEADER_MAGIC | (cls & HEADER_CLASS_MASK)); - *(uint8_t*)(uintptr_t)cur = expected; - } -#endif - // Rewrite next pointer to Box representation for this class - tiny_next_write(cls, (void*)cur, prev); - prev = (void*)cur; - cur = next; - } - meta->freelist = prev; - // Reset remote count after full drain - atomic_store_explicit(&ss->remote_counts[slab_idx], 0, memory_order_release); - - // Update freelist/nonempty visibility bits - uint32_t bit = (1u << slab_idx); - atomic_fetch_or_explicit(&ss->freelist_mask, bit, memory_order_release); - atomic_fetch_or_explicit(&ss->nonempty_mask, bit, memory_order_release); -} +// g_ss_populate_once controls MAP_POPULATE flag (defined in superslab_ace.c) +extern _Atomic int g_ss_populate_once; // ============================================================================ // SuperSlab Allocation (ACE-Aware) @@ -260,7 +213,9 @@ SuperSlab* superslab_allocate(uint8_t size_class) { // Phase 12: Initialize next_chunk (legacy per-class chain) ss->next_chunk = NULL; - // Initialize all slab metadata (only up to max slabs for this size) + // Initialize all slab metadata (only up to max slabs for this size). + // NOTE: 詳細な Slab 初期化と Remote Queue Drain は superslab_slab.c + //(Slab Management Box)側に集約している。 int max_slabs = (int)(ss_size / SLAB_SIZE); // DEFENSIVE FIX: Zero all slab metadata arrays to prevent ANY uninitialized pointers @@ -275,18 +230,6 @@ SuperSlab* superslab_allocate(uint8_t size_class) { // This ensures class_map is in a known state even before slabs are assigned memset(ss->class_map, 255, max_slabs * sizeof(uint8_t)); - for (int i = 0; i < max_slabs; i++) { - ss_slab_meta_freelist_set(ss, i, NULL); // Explicit NULL (redundant after memset, but clear intent) - ss_slab_meta_used_set(ss, i, 0); - ss_slab_meta_capacity_set(ss, i, 0); - ss_slab_meta_owner_tid_low_set(ss, i, 0); - - // Initialize remote queue atomics (memset already zeroed, but use proper atomic init) - atomic_store_explicit(&ss->remote_heads[i], 0, memory_order_relaxed); - atomic_store_explicit(&ss->remote_counts[i], 0, memory_order_relaxed); - atomic_store_explicit(&ss->slab_listed[i], 0, memory_order_relaxed); - } - if (from_cache) { ss_stats_cache_reuse(); } @@ -388,8 +331,10 @@ void superslab_free(SuperSlab* ss) { return; } - // Phase E3-1: Check never-free policy before munmap + // Phase E3-1: Check never-free policy before munmap (DISABLED - policy field not yet implemented) // If policy forbids Tiny SuperSlab munmap, skip deallocation (leak is intentional) + // TODO: Add tiny_ss_never_free_global field to FrozenPolicy when implementing Phase E3-1 +#if 0 const FrozenPolicy* pol = hkm_policy_get(); if (pol && pol->tiny_ss_never_free_global) { // Policy forbids munmap - keep SuperSlab allocated (intentional "leak") @@ -400,6 +345,7 @@ void superslab_free(SuperSlab* ss) { #endif return; } +#endif // Both caches full - immediately free to OS (eager deallocation) // Clear magic to prevent use-after-free @@ -426,53 +372,8 @@ void superslab_free(SuperSlab* ss) { #endif } -// ============================================================================ +// ============================================================================ // Slab Initialization within SuperSlab -// ============================================================================ - -void superslab_init_slab(SuperSlab* ss, int slab_idx, size_t block_size, uint32_t owner_tid) -{ - if (!ss || slab_idx < 0 || slab_idx >= ss_slabs_capacity(ss)) { - return; - } - - // Phase E1-CORRECT unified geometry: - // - block_size is the TOTAL stride for this class (g_tiny_class_sizes[cls]) - // - usable bytes are determined by slab index (slab0 vs others) - // - capacity = usable / stride for ALL classes (including former C7) - size_t usable_size = (slab_idx == 0) - ? SUPERSLAB_SLAB0_USABLE_SIZE - : SUPERSLAB_SLAB_USABLE_SIZE; - size_t stride = block_size; - uint16_t capacity = (uint16_t)(usable_size / stride); - -#if !HAKMEM_BUILD_RELEASE - if (slab_idx == 0) { - fprintf(stderr, - "[SUPERSLAB_INIT] slab 0: usable_size=%zu stride=%zu capacity=%u\n", - usable_size, stride, (unsigned)capacity); - } -#endif - - TinySlabMeta* meta = &ss->slabs[slab_idx]; - meta->freelist = NULL; // NULL = linear allocation mode - meta->used = 0; - meta->active = 0; // P1.3: blocks in use by user (starts at 0) - meta->tls_cached = 0; // P2.2: blocks cached in TLS SLL (starts at 0) - meta->capacity = capacity; - meta->carved = 0; - // Store bits 8-15 of owner_tid (low 8 bits are 0 for glibc pthread IDs) - meta->owner_tid_low = (uint8_t)((owner_tid >> 8) & 0xFFu); - // Fail-safe: stamp class_idx from geometry (stride → class). - // This normalizes both legacy and shared pool paths. - for (int i = 0; i < TINY_NUM_CLASSES; i++) { - if (g_tiny_class_sizes[i] == stride) { - meta->class_idx = (uint8_t)i; - // P1.1: Update class_map for out-of-band lookup on free path - ss->class_map[slab_idx] = (uint8_t)i; - break; - } - } - - superslab_activate_slab(ss, slab_idx); -} +// ============================================================================ +// Note: superslab_init_slab() は superslab_slab.c(Slab Management Box) +// に実装されており、この Box では export しない。 diff --git a/core/box/ss_allocation_box.h b/core/box/ss_allocation_box.h index 616b56d9..a5c04154 100644 --- a/core/box/ss_allocation_box.h +++ b/core/box/ss_allocation_box.h @@ -1,11 +1,10 @@ // Box: Core Allocation -// Purpose: SuperSlab allocation/deallocation and slab initialization +// Purpose: SuperSlab allocation/deallocation(割り当ての出入口 Box) // // Responsibilities: // - Allocate SuperSlab with ACE-aware sizing // - Free SuperSlab with LRU cache integration -// - Initialize slab metadata (capacity, stride, freelist) -// - Drain remote MPSC stack to freelist +// - Defer slab‑level details to Slab Management Box // // Dependencies: // - ss_os_acquire_box (OS-level mmap/munmap) @@ -18,8 +17,6 @@ // API: // - superslab_allocate() - main allocation entry // - superslab_free() - deallocation with LRU cache -// - superslab_init_slab() - slab metadata initialization -// - _ss_remote_drain_to_freelist_unsafe() - remote drain helper #ifndef SS_ALLOCATION_BOX_H #define SS_ALLOCATION_BOX_H @@ -33,10 +30,4 @@ SuperSlab* superslab_allocate(uint8_t size_class); // SuperSlab deallocation (LRU cache integration) void superslab_free(SuperSlab* ss); -// Slab initialization -void superslab_init_slab(SuperSlab* ss, int slab_idx, size_t block_size, uint32_t owner_tid); - -// Remote drain helper (ownership already verified by caller) -void _ss_remote_drain_to_freelist_unsafe(SuperSlab* ss, int slab_idx, TinySlabMeta* meta); - #endif // SS_ALLOCATION_BOX_H diff --git a/core/hakmem.c b/core/hakmem.c index 3efc8a78..6a0ea584 100644 --- a/core/hakmem.c +++ b/core/hakmem.c @@ -300,16 +300,6 @@ static inline int hak_init_wait_for_ready(void) { return 1; // Init completed } -// ============================================================================ -// Phase 6-1.5: Ultra-Simple Fast Path Forward Declarations -// ============================================================================ -// Forward declarations for Phase 6 fast path variants -// Phase 6-1.5: Alignment guessing (hakmem_tiny_ultra_simple.inc) -#ifdef HAKMEM_TINY_PHASE6_ULTRA_SIMPLE -extern void* hak_tiny_alloc_ultra_simple(size_t size); -extern void hak_tiny_free_ultra_simple(void* ptr); -#endif - // Phase 6-1.6: Metadata header (hakmem_tiny_metadata.inc) #ifdef HAKMEM_TINY_PHASE6_METADATA extern void* hak_tiny_alloc_metadata(size_t size); diff --git a/core/hakmem_super_registry.c b/core/hakmem_super_registry.c index 2ce3c15f..c2b24a1d 100644 --- a/core/hakmem_super_registry.c +++ b/core/hakmem_super_registry.c @@ -296,6 +296,32 @@ static int ss_lru_evict_one(void) { SuperSlab* victim = g_ss_lru_cache.lru_tail; if (!victim) return 0; + // Safety guard: if the tail SuperSlab is no longer registered in the + // global registry, its memory may already have been unmapped by another + // path. In that case, dereferencing victim (or its lru_prev/next) is + // unsafe. Treat this as a stale LRU entry and conservatively reset the + // cache to an empty state instead of evicting. + // + // NOTE: hak_super_lookup() only consults the registry / address map and + // never dereferences the SuperSlab pointer itself, so this check is safe + // even if victim has been munmapped. + if (hak_super_lookup((void*)victim) == NULL) { +#if !HAKMEM_BUILD_RELEASE + static int stale_log_count = 0; + if (stale_log_count < 4) { + fprintf(stderr, + "[SS_LRU_STALE_TAIL] victim=%p not in registry; resetting LRU cache\n", + (void*)victim); + stale_log_count++; + } +#endif + g_ss_lru_cache.lru_head = NULL; + g_ss_lru_cache.lru_tail = NULL; + g_ss_lru_cache.total_count = 0; + g_ss_lru_cache.total_memory_mb = 0; + return 0; + } + // Remove from LRU list ss_lru_remove(victim); g_ss_lru_cache.total_count--; diff --git a/core/hakmem_tiny.c b/core/hakmem_tiny.c index 457da84a..2f8fdbfc 100644 --- a/core/hakmem_tiny.c +++ b/core/hakmem_tiny.c @@ -206,9 +206,11 @@ static inline int fastcache_push(int class_idx, hak_base_ptr_t ptr); // ============================================================================ -// Legacy Slow Allocation Path - EXTRACTED to hakmem_tiny_legacy_slow_box.inc +// Legacy Slow Allocation Path - ARCHIVED // ============================================================================ -#include "hakmem_tiny_legacy_slow_box.inc" +// Note: tiny_slow_alloc_fast() and related legacy slow path implementation +// have been moved to archive/hakmem_tiny_legacy_slow_box.inc and are no +// longer compiled. The current slow path uses Box化された hak_tiny_alloc_slow(). // ============================================================================ @@ -493,18 +495,9 @@ static inline void* hak_tiny_alloc_superslab_try_fast(int class_idx) { #include "hakmem_tiny_smallmag.inc.h" // ============================================================================ -// Phase 6 Fast Path Options (mutually exclusive) +// Phase 6 Fast Path Option (Metadata Header) // ============================================================================ -// Choose ONE of the following Phase 6 optimizations: -// -// Phase 6-1.5: Alignment Guessing (LEGACY - committed 2025-11-02) -// - Enable: -DHAKMEM_TINY_PHASE6_ULTRA_SIMPLE=1 -// - Speed: 235 M ops/sec -// - Memory: 0% overhead -// - Method: Guess size class from pointer alignment (__builtin_ctzl) -// - Risk: Alignment assumptions may break with future changes -// -// Phase 6-1.6: Metadata Header (NEW - recommended for production) +// Phase 6-1.6: Metadata Header (recommended) // - Enable: -DHAKMEM_TINY_PHASE6_METADATA=1 // - Speed: 450-480 M ops/sec (expected, Phase 6-1 level) // - Memory: ~6-12% overhead (8 bytes/allocation) @@ -514,14 +507,6 @@ static inline void* hak_tiny_alloc_superslab_try_fast(int class_idx) { // ============================================================================ // Forward declarations for Phase 6 alloc/free functions -#ifdef HAKMEM_TINY_PHASE6_ULTRA_SIMPLE - void* hak_tiny_alloc_ultra_simple(size_t size); - void hak_tiny_free_ultra_simple(void* ptr); -#endif - -#if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) - #error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE" -#endif // ============================================================================ diff --git a/core/hakmem_tiny_alloc.inc b/core/hakmem_tiny_alloc.inc index c0227f90..29efcd44 100644 --- a/core/hakmem_tiny_alloc.inc +++ b/core/hakmem_tiny_alloc.inc @@ -135,17 +135,16 @@ void* hak_tiny_alloc(size_t size) { hak_tiny_stats_poll(); // ======================================================================== - // Phase 6-1.5: Ultra-Simple Fast Path (when enabled) + // Phase 6-1.6: Metadata Header Front (optional) // ======================================================================== // Design: "Simple Front + Smart Back" - inspired by Mid-Large HAKX +171% // - 3-4 instruction fast path (Phase 6-1 style) // - Existing SuperSlab + ACE + Learning backend - // Two variants: - // Phase 6-1.5: -DHAKMEM_TINY_PHASE6_ULTRA_SIMPLE=1 (alignment guessing) - // Phase 6-1.6: -DHAKMEM_TINY_PHASE6_METADATA=1 (metadata header) -#ifdef HAKMEM_TINY_PHASE6_ULTRA_SIMPLE - return hak_tiny_alloc_ultra_simple(size); -#elif defined(HAKMEM_TINY_PHASE6_METADATA) + // + // NOTE: + // - Phase 6-1.5 (HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) はレガシー経路として + // アーカイブ済み。現在は Metadata variant のみサポート。 +#ifdef HAKMEM_TINY_PHASE6_METADATA return hak_tiny_alloc_metadata(size); #endif // ======================================================================== diff --git a/core/hakmem_tiny_phase6_wrappers_box.inc b/core/hakmem_tiny_phase6_wrappers_box.inc index 4bed7e85..7029fd07 100644 --- a/core/hakmem_tiny_phase6_wrappers_box.inc +++ b/core/hakmem_tiny_phase6_wrappers_box.inc @@ -1,6 +1,6 @@ // Phase 6-1.7: Box Theory Refactoring - Mutual exclusion check #if HAKMEM_TINY_PHASE6_BOX_REFACTOR - #if defined(HAKMEM_TINY_PHASE6_METADATA) || defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) + #if defined(HAKMEM_TINY_PHASE6_METADATA) #error "Cannot enable PHASE6_BOX_REFACTOR with other Phase 6 options" #endif @@ -94,7 +94,7 @@ } } -// HAKMEM_TINY_PHASE6_ULTRA_SIMPLE - REMOVED (dead code cleanup 2025-11-27) +// Metadata-only fallback when Box Refactor is disabled #elif defined(HAKMEM_TINY_PHASE6_METADATA) // Phase 6-1.6: Metadata header (recommended) #include "hakmem_tiny_metadata.inc" diff --git a/core/ptr_trace.h b/core/ptr_trace.h index 0db26ac6..fe1726ab 100644 --- a/core/ptr_trace.h +++ b/core/ptr_trace.h @@ -119,9 +119,10 @@ static inline void ptr_trace_dump_now(const char* reason) { (void)reason; } g_tiny_next_tag = (tag); \ g_tiny_next_file = __FILE__; \ g_tiny_next_line = __LINE__; \ + /* Use only depth-0 return address; deeper frames are unsafe. */ \ g_tiny_next_ra0 = __builtin_return_address(0); \ - g_tiny_next_ra1 = __builtin_return_address(1); \ - g_tiny_next_ra2 = __builtin_return_address(2); \ + g_tiny_next_ra1 = NULL; \ + g_tiny_next_ra2 = NULL; \ (void)(off); \ tiny_next_write((cls), (node), (value)); \ ptr_trace_record((tag), (cls), (node), (value), (size_t)(off)); \ @@ -145,9 +146,10 @@ static inline void ptr_trace_dump_now(const char* reason) { (void)reason; } g_tiny_next_tag = (tag); \ g_tiny_next_file = __FILE__; \ g_tiny_next_line = __LINE__; \ + /* Depth-0 return address only; avoid unsafe frame walks. */ \ g_tiny_next_ra0 = __builtin_return_address(0); \ - g_tiny_next_ra1 = __builtin_return_address(1); \ - g_tiny_next_ra2 = __builtin_return_address(2); \ + g_tiny_next_ra1 = NULL; \ + g_tiny_next_ra2 = NULL; \ (void)(tag); (void)(off); \ tiny_next_write((cls), (node), (value)); \ } while (0) diff --git a/core/superslab/superslab_inline.h b/core/superslab/superslab_inline.h index 3cf4d5ed..4b9ed9d5 100644 --- a/core/superslab/superslab_inline.h +++ b/core/superslab/superslab_inline.h @@ -30,10 +30,10 @@ extern _Atomic uint64_t g_ss_active_dec_calls; // - ss_lookup_guarded() : 100-200 cycles, adds integrity checks // - ss_fast_lookup() : Backward compatible (→ ss_lookup_safe) // -// Note: hak_super_lookup() is implemented in hakmem_super_registry.h as static inline -// The circular dependency (this file ↔ hakmem_super_registry.h) is resolved because: -// - hakmem_super_registry.h is included before this file in hakmem_tiny_superslab.h -// - By the time functions here are instantiated, hak_super_lookup() is already defined +// Note: hak_super_lookup() is implemented in hakmem_super_registry.h as static inline. +// We provide a forward declaration here so that ss_lookup_guarded() can call it +// even in translation units where hakmem_super_registry.h is included later. +static inline SuperSlab* hak_super_lookup(void* ptr); // ============================================================================ // Contract Level 1: UNSAFE - Fast but dangerous (internal use only) diff --git a/core/superslab_cache.c b/core/superslab_cache.c index d26bef6d..92dc808f 100644 --- a/core/superslab_cache.c +++ b/core/superslab_cache.c @@ -202,3 +202,78 @@ int ss_cache_push(uint8_t size_class, SuperSlab* ss) { pthread_mutex_unlock(&g_ss_cache_lock[size_class]); return 1; } + +// ============================================================================ +// Precharge Configuration API +// ============================================================================ + +void tiny_ss_precharge_set_class_target(int class_idx, size_t target) { + if (class_idx < 0 || class_idx >= 8) { + return; + } + + ss_cache_ensure_init(); + pthread_mutex_lock(&g_ss_cache_lock[class_idx]); + + g_ss_precharge_target[class_idx] = target; + if (target > 0) { + g_ss_cache_enabled = 1; + atomic_store_explicit(&g_ss_precharge_done[class_idx], 0, memory_order_relaxed); + } + + pthread_mutex_unlock(&g_ss_cache_lock[class_idx]); +} + +void tiny_ss_cache_set_class_cap(int class_idx, size_t new_cap) { + if (class_idx < 0 || class_idx >= 8) { + return; + } + + ss_cache_ensure_init(); + pthread_mutex_lock(&g_ss_cache_lock[class_idx]); + + size_t old_cap = g_ss_cache_cap[class_idx]; + g_ss_cache_cap[class_idx] = new_cap; + + // If shrinking cap, drop extra cached superslabs (oldest from head) and munmap them. + if (new_cap == 0 || new_cap < old_cap) { + while (g_ss_cache_count[class_idx] > new_cap) { + SuperslabCacheEntry* entry = g_ss_cache_head[class_idx]; + if (!entry) { + g_ss_cache_count[class_idx] = 0; + break; + } + g_ss_cache_head[class_idx] = entry->next; + g_ss_cache_count[class_idx]--; + g_ss_cache_drops[class_idx]++; + + // Convert cache entry back to SuperSlab* and release it to OS. + SuperSlab* ss = (SuperSlab*)entry; + size_t ss_size = (size_t)1 << ss->lg_size; + munmap((void*)ss, ss_size); + + // Update global stats to keep accounting consistent. + extern pthread_mutex_t g_superslab_lock; // From ss_stats_box.c + pthread_mutex_lock(&g_superslab_lock); + g_superslabs_freed++; + if (g_bytes_allocated >= ss_size) { + g_bytes_allocated -= ss_size; + } else { + g_bytes_allocated = 0; + } + pthread_mutex_unlock(&g_superslab_lock); + } + } + + pthread_mutex_unlock(&g_ss_cache_lock[class_idx]); + + // Recompute cache enabled flag (8 classes, so O(8) is cheap) + int enabled = 0; + for (int i = 0; i < 8; i++) { + if (g_ss_cache_cap[i] > 0 || g_ss_precharge_target[i] > 0) { + enabled = 1; + break; + } + } + g_ss_cache_enabled = enabled; +} diff --git a/core/superslab_head_stub.c b/core/superslab_head_stub.c new file mode 100644 index 00000000..0e8a38a3 --- /dev/null +++ b/core/superslab_head_stub.c @@ -0,0 +1,41 @@ +// superslab_head_stub.c - Legacy SuperSlabHead stubs +// Purpose: Provide minimal symbols for legacy SuperSlabHead API while +// the full implementation is archived. +// +// Notes: +// - The real SuperSlabHead implementation lives in +// archive/superslab_head_legacy.c +// - Current backend uses shared pool + LRU Box; g_superslab_heads is no +// longer populated in production paths. +// - These stubs keep the ABI/linkage stable and are effectively no-ops. + +#include "hakmem_tiny_superslab_internal.h" + +SuperSlabHead* g_superslab_heads[TINY_NUM_CLASSES_SS] = {NULL}; + +SuperSlabHead* init_superslab_head(int class_idx) +{ + (void)class_idx; + return NULL; +} + +int expand_superslab_head(SuperSlabHead* head) +{ + (void)head; + // No legacy expansion; shared pool backend handles growth. + return -1; +} + +SuperSlab* find_chunk_for_ptr(void* ptr, int class_idx) +{ + (void)ptr; + (void)class_idx; + return NULL; +} + +void remove_superslab_from_legacy_head(SuperSlab* ss) +{ + (void)ss; + // Legacy list is unused; nothing to do. +} + diff --git a/hakmem.d b/hakmem.d index 0ae5ff33..67ca6b97 100644 --- a/hakmem.d +++ b/hakmem.d @@ -27,15 +27,14 @@ hakmem.o: core/hakmem.c core/hakmem.h core/hakmem_build_flags.h \ core/box/hak_core_init.inc.h core/hakmem_phase7_config.h \ core/box/ss_hot_prewarm_box.h core/box/hak_alloc_api.inc.h \ core/box/../hakmem_tiny.h core/box/../hakmem_pool.h \ - core/box/../hakmem_smallmid.h core/box/../pool_tls.h \ - core/box/mid_large_config_box.h core/box/../hakmem_config.h \ - core/box/../hakmem_features.h core/box/hak_free_api.inc.h \ - core/hakmem_tiny_superslab.h core/box/front_gate_v2.h \ - core/box/external_guard_box.h core/box/ss_slab_meta_box.h \ - core/box/../superslab/superslab_types.h core/box/slab_freelist_atomic.h \ - core/box/fg_tiny_gate_box.h core/box/tiny_free_gate_box.h \ - core/box/ptr_type_box.h core/box/ptr_conversion_box.h \ - core/box/tiny_ptr_bridge_box.h \ + core/box/../hakmem_smallmid.h core/box/mid_large_config_box.h \ + core/box/../hakmem_config.h core/box/../hakmem_features.h \ + core/box/hak_free_api.inc.h core/hakmem_tiny_superslab.h \ + core/box/front_gate_v2.h core/box/external_guard_box.h \ + core/box/ss_slab_meta_box.h core/box/../superslab/superslab_types.h \ + core/box/slab_freelist_atomic.h core/box/fg_tiny_gate_box.h \ + core/box/tiny_free_gate_box.h core/box/ptr_type_box.h \ + core/box/ptr_conversion_box.h core/box/tiny_ptr_bridge_box.h \ core/box/../hakmem_tiny_superslab_internal.h \ core/box/../hakmem_build_flags.h core/box/../hakmem_tiny_superslab.h \ core/box/../box/ss_hot_cold_box.h \ @@ -156,7 +155,6 @@ core/box/hak_alloc_api.inc.h: core/box/../hakmem_tiny.h: core/box/../hakmem_pool.h: core/box/../hakmem_smallmid.h: -core/box/../pool_tls.h: core/box/mid_large_config_box.h: core/box/../hakmem_config.h: core/box/../hakmem_features.h: