diff --git a/core/box/mailbox_box.d b/core/box/mailbox_box.d index ee5eec23..f2496cc1 100644 --- a/core/box/mailbox_box.d +++ b/core/box/mailbox_box.d @@ -6,7 +6,8 @@ core/box/mailbox_box.o: core/box/mailbox_box.c core/box/mailbox_box.h \ core/superslab/../hakmem_tiny_config.h core/tiny_debug_ring.h \ core/hakmem_build_flags.h core/tiny_remote.h \ core/hakmem_tiny_superslab_constants.h core/hakmem_tiny.h \ - core/hakmem_trace.h core/hakmem_tiny_mini_mag.h core/tiny_debug_ring.h + core/hakmem_trace.h core/hakmem_tiny_mini_mag.h \ + core/hakmem_trace_master.h core/tiny_debug_ring.h core/box/mailbox_box.h: core/hakmem_tiny_superslab.h: core/superslab/superslab_types.h: @@ -23,4 +24,5 @@ core/hakmem_tiny_superslab_constants.h: core/hakmem_tiny.h: core/hakmem_trace.h: core/hakmem_tiny_mini_mag.h: +core/hakmem_trace_master.h: core/tiny_debug_ring.h: diff --git a/core/box/pool_api.inc.h b/core/box/pool_api.inc.h index dd659a8f..b956b397 100644 --- a/core/box/pool_api.inc.h +++ b/core/box/pool_api.inc.h @@ -307,9 +307,32 @@ void hak_pool_free(void* ptr, size_t size, uintptr_t site_id) { if (same_thread) { PoolTLSRing* ring = &g_tls_bin[class_idx].ring; if (g_tls_ring_enabled && ring->top < POOL_L2_RING_CAP) { ring->items[ring->top++] = block; } - else { block->next = g_tls_bin[class_idx].lo_head; g_tls_bin[class_idx].lo_head = block; g_tls_bin[class_idx].lo_count++; if ((int)g_tls_bin[class_idx].lo_count > g_tls_lo_max) { - size_t spill = g_tls_bin[class_idx].lo_count / 2; int shard = hak_pool_get_shard_index(site_id); - while (spill-- && g_tls_bin[class_idx].lo_head) { PoolBlock* b = g_tls_bin[class_idx].lo_head; g_tls_bin[class_idx].lo_head = b->next; g_tls_bin[class_idx].lo_count--; HKM_TIME_START(t_remote_push1); uintptr_t old_head; do { old_head = atomic_load_explicit(&g_pool.remote_head[class_idx][shard], memory_order_acquire); b->next = (PoolBlock*)old_head; } while (!atomic_compare_exchange_weak_explicit(&g_pool.remote_head[class_idx][shard], &old_head, (uintptr_t)b, memory_order_release, memory_order_relaxed)); atomic_fetch_add_explicit(&g_pool.remote_count[class_idx][shard], 1, memory_order_relaxed); HKM_TIME_END(HKM_CAT_POOL_REMOTE_PUSH, t_remote_push1); } set_nonempty_bit(class_idx, shard); } } + else { + block->next = g_tls_bin[class_idx].lo_head; + g_tls_bin[class_idx].lo_head = block; + g_tls_bin[class_idx].lo_count++; + if ((int)g_tls_bin[class_idx].lo_count > g_tls_lo_max) { + size_t spill = g_tls_bin[class_idx].lo_count / 2; + int shard = hak_pool_get_shard_index(site_id); + // Spill half of local freelist to remote freelist + while (spill-- && g_tls_bin[class_idx].lo_head) { + PoolBlock* b = g_tls_bin[class_idx].lo_head; + g_tls_bin[class_idx].lo_head = b->next; + g_tls_bin[class_idx].lo_count--; + HKM_TIME_START(t_remote_push1); + uintptr_t old_head; + do { + old_head = atomic_load_explicit(&g_pool.remote_head[class_idx][shard], memory_order_acquire); + b->next = (PoolBlock*)old_head; + } while (!atomic_compare_exchange_weak_explicit(&g_pool.remote_head[class_idx][shard], + &old_head, (uintptr_t)b, + memory_order_release, memory_order_relaxed)); + atomic_fetch_add_explicit(&g_pool.remote_count[class_idx][shard], 1, memory_order_relaxed); + HKM_TIME_END(HKM_CAT_POOL_REMOTE_PUSH, t_remote_push1); + } + set_nonempty_bit(class_idx, shard); + } + } } else { if (g_tc_enabled) { uint64_t owner_tid = 0; if (g_hdr_light_enabled < 2) owner_tid = hdr->owner_tid; if (owner_tid == 0) { MidPageDesc* d = mid_desc_lookup(raw); if (d) owner_tid = d->owner_tid; } if (owner_tid != 0) { MidTC* otc = mid_tc_lookup_by_tid(owner_tid); if (otc) { mid_tc_push(otc, class_idx, block); return; } } } int shard = hak_pool_get_shard_index(site_id); uintptr_t old_head; HKM_TIME_START(t_remote_push2); diff --git a/hakmem_elo.d b/hakmem_elo.d index 70e18062..8154d31c 100644 --- a/hakmem_elo.d +++ b/hakmem_elo.d @@ -1,7 +1,9 @@ -hakmem_elo.o: core/hakmem_elo.c core/hakmem_elo.h core/hakmem_internal.h \ - core/hakmem.h core/hakmem_build_flags.h core/hakmem_config.h \ - core/hakmem_features.h core/hakmem_sys.h core/hakmem_whale.h +hakmem_elo.o: core/hakmem_elo.c core/hakmem_elo.h \ + core/hakmem_debug_master.h core/hakmem_internal.h core/hakmem.h \ + core/hakmem_build_flags.h core/hakmem_config.h core/hakmem_features.h \ + core/hakmem_sys.h core/hakmem_whale.h core/hakmem_elo.h: +core/hakmem_debug_master.h: core/hakmem_internal.h: core/hakmem.h: core/hakmem_build_flags.h: diff --git a/hakmem_shared_pool.d b/hakmem_shared_pool.d index 8d572a04..10f3b7e2 100644 --- a/hakmem_shared_pool.d +++ b/hakmem_shared_pool.d @@ -5,7 +5,8 @@ hakmem_shared_pool.o: core/hakmem_shared_pool.c core/hakmem_shared_pool.h \ core/superslab/../hakmem_tiny_superslab_constants.h \ core/superslab/../hakmem_tiny_config.h core/tiny_debug_ring.h \ core/hakmem_build_flags.h core/tiny_remote.h \ - core/hakmem_tiny_superslab_constants.h core/box/ss_slab_meta_box.h \ + core/hakmem_tiny_superslab_constants.h core/hakmem_debug_master.h \ + core/hakmem_stats_master.h core/box/ss_slab_meta_box.h \ core/box/../superslab/superslab_types.h core/box/slab_freelist_atomic.h \ core/box/tiny_next_ptr_box.h core/hakmem_tiny_config.h \ core/tiny_nextptr.h core/tiny_region_id.h core/tiny_box_geometry.h \ @@ -19,7 +20,7 @@ hakmem_shared_pool.o: core/hakmem_shared_pool.c core/hakmem_shared_pool.h \ core/box/../ptr_track.h core/box/../ptr_trace.h \ core/box/../tiny_debug_ring.h core/box/../superslab/superslab_inline.h \ core/box/free_local_box.h core/hakmem_tiny_superslab.h \ - core/hakmem_policy.h + core/box/tls_slab_reuse_guard_box.h core/hakmem_policy.h core/hakmem_shared_pool.h: core/superslab/superslab_types.h: core/hakmem_tiny_superslab_constants.h: @@ -33,6 +34,8 @@ core/tiny_debug_ring.h: core/hakmem_build_flags.h: core/tiny_remote.h: core/hakmem_tiny_superslab_constants.h: +core/hakmem_debug_master.h: +core/hakmem_stats_master.h: core/box/ss_slab_meta_box.h: core/box/../superslab/superslab_types.h: core/box/slab_freelist_atomic.h: @@ -62,4 +65,5 @@ core/box/../tiny_debug_ring.h: core/box/../superslab/superslab_inline.h: core/box/free_local_box.h: core/hakmem_tiny_superslab.h: +core/box/tls_slab_reuse_guard_box.h: core/hakmem_policy.h: diff --git a/hakmem_tiny_sfc.d b/hakmem_tiny_sfc.d index 992a436e..8695e7da 100644 --- a/hakmem_tiny_sfc.d +++ b/hakmem_tiny_sfc.d @@ -7,8 +7,8 @@ hakmem_tiny_sfc.o: core/hakmem_tiny_sfc.c core/tiny_alloc_fast_sfc.inc.h \ core/hakmem_tiny_superslab.h core/superslab/superslab_types.h \ core/hakmem_tiny_superslab_constants.h core/superslab/superslab_inline.h \ core/superslab/superslab_types.h core/superslab/../tiny_box_geometry.h \ - core/tiny_debug_ring.h core/tiny_remote.h core/tiny_tls.h \ - core/box/tls_sll_box.h core/box/../hakmem_tiny_config.h \ + core/tiny_debug_ring.h core/tiny_remote.h core/hakmem_stats_master.h \ + core/tiny_tls.h core/box/tls_sll_box.h core/box/../hakmem_tiny_config.h \ core/box/../hakmem_build_flags.h core/box/../tiny_remote.h \ core/box/../tiny_region_id.h core/box/../hakmem_tiny_integrity.h \ core/box/../hakmem_tiny.h core/box/../ptr_track.h \ @@ -36,6 +36,7 @@ core/superslab/superslab_types.h: core/superslab/../tiny_box_geometry.h: core/tiny_debug_ring.h: core/tiny_remote.h: +core/hakmem_stats_master.h: core/tiny_tls.h: core/box/tls_sll_box.h: core/box/../hakmem_tiny_config.h: diff --git a/verify_fix_20runs.sh b/verify_fix_20runs.sh new file mode 100755 index 00000000..2e55b634 --- /dev/null +++ b/verify_fix_20runs.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# Destructor Crash Fix Verification Script +# Purpose: Run 20 development build benchmarks to verify crash fix +# Expected: 0% crash rate (previously 50%) + +echo "=========================================" +echo "Destructor Crash Fix Verification" +echo "=========================================" +echo "Target: 20 successful runs" +echo "Build Mode: Development (HAKMEM_BUILD_RELEASE=0)" +echo "Expected Performance: ~30.7M ops/s" +echo "" + +# Ensure we're in development build mode +export HAKMEM_BUILD_RELEASE=0 + +# Arrays to store results +declare -a throughputs +declare -a statuses +total_runs=20 +success_count=0 +crash_count=0 + +echo "Starting 20-run verification test..." +echo "" + +for i in $(seq 1 $total_runs); do + echo "=========================================" + echo "Run $i/$total_runs" + echo "=========================================" + + # Run the benchmark and capture output and exit code + output=$(./larson_hakmem 1 10 1 1000 100 10000 42 2>&1) + exit_code=$? + + # Check if benchmark completed successfully + if echo "$output" | grep -q "Throughput" && [ $exit_code -eq 0 ]; then + # Extract throughput value + throughput=$(echo "$output" | grep "Throughput" | awk '{print $3}') + throughputs+=("$throughput") + statuses+=("SUCCESS") + success_count=$((success_count + 1)) + echo "✓ SUCCESS: $throughput ops/s" + else + throughputs+=("0") + statuses+=("CRASH") + crash_count=$((crash_count + 1)) + echo "✗ CRASHED (exit code: $exit_code)" + echo "Last few lines of output:" + echo "$output" | tail -5 + fi + + echo "" + sleep 1 # Brief pause between runs +done + +echo "" +echo "=========================================" +echo "FINAL RESULTS SUMMARY" +echo "=========================================" +echo "" +echo "Execution Statistics:" +echo " Total Runs: $total_runs" +echo " Successful: $success_count" +echo " Crashed: $crash_count" +echo " Success Rate: $(awk "BEGIN {printf \"%.1f%%\", ($success_count/$total_runs)*100}")" +echo " Crash Rate: $(awk "BEGIN {printf \"%.1f%%\", ($crash_count/$total_runs)*100}")" +echo "" + +if [ $success_count -gt 0 ]; then + echo "Performance Statistics (Successful Runs):" + + # Calculate mean + sum=0 + for tp in "${throughputs[@]}"; do + if [ "$tp" != "0" ]; then + sum=$(awk "BEGIN {print $sum + $tp}") + fi + done + mean=$(awk "BEGIN {printf \"%.2f\", $sum/$success_count}") + echo " Mean: $mean M ops/s" + + # Calculate min and max + min=999999999 + max=0 + for tp in "${throughputs[@]}"; do + if [ "$tp" != "0" ]; then + if (( $(awk "BEGIN {print ($tp < $min)}") )); then + min=$tp + fi + if (( $(awk "BEGIN {print ($tp > $max)}") )); then + max=$tp + fi + fi + done + echo " Min: $min M ops/s" + echo " Max: $max M ops/s" + echo " Range: $(awk "BEGIN {printf \"%.2f\", $max - $min}") M ops/s" + + # Calculate standard deviation + variance=0 + for tp in "${throughputs[@]}"; do + if [ "$tp" != "0" ]; then + diff=$(awk "BEGIN {print $tp - $mean}") + variance=$(awk "BEGIN {print $variance + ($diff * $diff)}") + fi + done + variance=$(awk "BEGIN {print $variance / $success_count}") + stddev=$(awk "BEGIN {printf \"%.2f\", sqrt($variance)}") + echo " Std Deviation: $stddev M ops/s" + + # Calculate coefficient of variation + cv=$(awk "BEGIN {printf \"%.2f%%\", ($stddev/$mean)*100}") + echo " Variation: $cv" + + # Compare to expected performance + expected=30.7 + deviation=$(awk "BEGIN {printf \"%.2f%%\", (($mean - $expected)/$expected)*100}") + echo "" + echo "Comparison to Phase 4a Baseline (30.7M ops/s):" + echo " Deviation: $deviation" +fi + +echo "" +echo "Detailed Run-by-Run Results:" +echo "Run# Status Throughput (M ops/s)" +echo "---- ------- -------------------" +for i in $(seq 0 $((total_runs - 1))); do + status="${statuses[$i]}" + tp="${throughputs[$i]}" + if [ "$tp" == "0" ]; then + printf "%-4d %-7s %s\n" $((i + 1)) "$status" "N/A" + else + printf "%-4d %-7s %s\n" $((i + 1)) "$status" "$tp" + fi +done + +echo "" +echo "=========================================" +echo "VERIFICATION CONCLUSION" +echo "=========================================" +if [ $crash_count -eq 0 ]; then + echo "✓ PASS: No crashes detected in 20 runs" + echo " Previous crash rate: 50%" + echo " Current crash rate: 0%" + echo " Improvement: 100% crash elimination" +else + echo "✗ FAIL: Crashes still occurring" + echo " Expected: 0 crashes" + echo " Actual: $crash_count crashes" + echo " This indicates the fix may be incomplete" +fi + +echo "" +echo "Test completed at $(date)" +echo "========================================="