Phase 1 Commit: Comprehensive documentation and build system cleanup Added Documentation: - BENCHMARK_SUMMARY_20251122.md: Current performance baseline - COMPREHENSIVE_BENCHMARK_REPORT_20251122.md: Detailed analysis - LARSON_SLOWDOWN_INVESTIGATION_REPORT.md: Larson benchmark deep dive - ATOMIC_FREELIST_*.md (5 files): Complete atomic freelist documentation - Implementation strategy, quick start, site-by-site guide - Index and summary for easy navigation Added Scripts: - run_comprehensive_benchmark.sh: Automated benchmark runner - scripts/analyze_freelist_sites.sh: Freelist analysis tool - scripts/verify_atomic_freelist_conversion.sh: Conversion verification Build System: - Updated .gitignore: Added *.d (build dependency files) - Cleaned up tracked .d files (will be ignored going forward) Performance Status (2025-11-22): - Random Mixed 256B: 59.6M ops/s (VERIFIED WORKING) - Benchmark command: ./out/release/bench_random_mixed_hakmem 10000000 256 42 - Known issue: workset=8192 causes SEGV (to be fixed separately) Notes: - bench_random_mixed.c already tracked, working state confirmed - Ultra SLIM implementation backed up to /tmp/ (Phase 2 restore pending) - Documentation covers atomic freelist conversion and benchmarking methodology 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
256 lines
9.6 KiB
Bash
Executable File
256 lines
9.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# verify_atomic_freelist_conversion.sh - Track atomic freelist conversion progress
|
|
|
|
set -e
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# Color codes
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
echo "========================================"
|
|
echo "Atomic Freelist Conversion Verification"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
# Check if accessor header exists
|
|
echo "=== ACCESSOR HEADER CHECK ==="
|
|
if [ -f "core/box/slab_freelist_atomic.h" ]; then
|
|
echo -e "${GREEN}✅ core/box/slab_freelist_atomic.h exists${NC}"
|
|
|
|
# Check if it has required functions
|
|
if grep -q "slab_freelist_pop_lockfree" core/box/slab_freelist_atomic.h; then
|
|
echo -e "${GREEN}✅ slab_freelist_pop_lockfree() defined${NC}"
|
|
else
|
|
echo -e "${RED}❌ slab_freelist_pop_lockfree() NOT FOUND${NC}"
|
|
fi
|
|
|
|
if grep -q "slab_freelist_push_lockfree" core/box/slab_freelist_atomic.h; then
|
|
echo -e "${GREEN}✅ slab_freelist_push_lockfree() defined${NC}"
|
|
else
|
|
echo -e "${RED}❌ slab_freelist_push_lockfree() NOT FOUND${NC}"
|
|
fi
|
|
|
|
if grep -q "slab_freelist_is_empty" core/box/slab_freelist_atomic.h; then
|
|
echo -e "${GREEN}✅ slab_freelist_is_empty() defined${NC}"
|
|
else
|
|
echo -e "${RED}❌ slab_freelist_is_empty() NOT FOUND${NC}"
|
|
fi
|
|
else
|
|
echo -e "${YELLOW}⚠️ core/box/slab_freelist_atomic.h does NOT exist yet${NC}"
|
|
echo " Run: cp core/box/slab_freelist_atomic.h.TEMPLATE core/box/slab_freelist_atomic.h"
|
|
fi
|
|
echo ""
|
|
|
|
# Count remaining direct accesses
|
|
echo "=== DIRECT ACCESS CHECK ==="
|
|
DIRECT_ACCESSES=$(grep -rn "meta->freelist" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l)
|
|
echo "Total 'meta->freelist' occurrences: ${DIRECT_ACCESSES}"
|
|
|
|
# Count converted sites
|
|
CONVERTED_CHECKS=$(grep -rn "slab_freelist_is_empty\|slab_freelist_is_nonempty" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l || echo "0")
|
|
CONVERTED_POPS=$(grep -rn "slab_freelist_pop_lockfree" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l || echo "0")
|
|
CONVERTED_PUSHES=$(grep -rn "slab_freelist_push_lockfree" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l || echo "0")
|
|
CONVERTED_LOADS=$(grep -rn "slab_freelist_load_relaxed" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l || echo "0")
|
|
CONVERTED_STORES=$(grep -rn "slab_freelist_store_relaxed" core/ --include="*.c" --include="*.h" 2>/dev/null | wc -l || echo "0")
|
|
|
|
echo "Converted operations:"
|
|
echo " NULL checks: ${CONVERTED_CHECKS}"
|
|
echo " POP operations: ${CONVERTED_POPS}"
|
|
echo " PUSH operations: ${CONVERTED_PUSHES}"
|
|
echo " Load operations: ${CONVERTED_LOADS}"
|
|
echo " Store operations: ${CONVERTED_STORES}"
|
|
|
|
TOTAL_CONVERTED=$((CONVERTED_CHECKS + CONVERTED_POPS + CONVERTED_PUSHES + CONVERTED_LOADS + CONVERTED_STORES))
|
|
echo -e "${BLUE}Total converted sites: ${TOTAL_CONVERTED}${NC}"
|
|
echo ""
|
|
|
|
# Estimate progress
|
|
BASELINE_TOTAL=90
|
|
if [ ${TOTAL_CONVERTED} -eq 0 ]; then
|
|
PROGRESS=0
|
|
else
|
|
PROGRESS=$((TOTAL_CONVERTED * 100 / BASELINE_TOTAL))
|
|
fi
|
|
|
|
echo "=== CONVERSION PROGRESS ==="
|
|
echo -e "Progress: ${BLUE}${PROGRESS}%${NC} (${TOTAL_CONVERTED}/${BASELINE_TOTAL} sites)"
|
|
|
|
# Progress bar
|
|
BAR_WIDTH=40
|
|
FILLED=$((PROGRESS * BAR_WIDTH / 100))
|
|
EMPTY=$((BAR_WIDTH - FILLED))
|
|
printf "["
|
|
printf "%${FILLED}s" | tr ' ' '='
|
|
printf "%${EMPTY}s" | tr ' ' '-'
|
|
printf "]\n"
|
|
echo ""
|
|
|
|
# Check Phase 1 files
|
|
echo "=== PHASE 1 FILES CHECK ==="
|
|
PHASE1_FILES=(
|
|
"core/tiny_superslab_alloc.inc.h"
|
|
"core/hakmem_tiny_refill_p0.inc.h"
|
|
"core/box/carve_push_box.c"
|
|
"core/hakmem_tiny_tls_ops.h"
|
|
)
|
|
|
|
PHASE1_DONE=0
|
|
for file in "${PHASE1_FILES[@]}"; do
|
|
if [ -f "$file" ]; then
|
|
# Check if file includes atomic header
|
|
if grep -q "slab_freelist_atomic.h" "$file"; then
|
|
echo -e "${GREEN}✅ $file (includes atomic.h)${NC}"
|
|
PHASE1_DONE=$((PHASE1_DONE + 1))
|
|
else
|
|
echo -e "${YELLOW}⚠️ $file (not converted yet)${NC}"
|
|
fi
|
|
else
|
|
echo -e "${RED}❌ $file (not found)${NC}"
|
|
fi
|
|
done
|
|
|
|
echo "Phase 1 files converted: ${PHASE1_DONE}/${#PHASE1_FILES[@]}"
|
|
echo ""
|
|
|
|
# Check for potential bugs
|
|
echo "=== POTENTIAL BUG CHECK ==="
|
|
|
|
# Check for double POP (pop + tiny_next_read)
|
|
DOUBLE_POP=$(grep -A1 "slab_freelist_pop_lockfree" core/ -r --include="*.c" --include="*.h" 2>/dev/null | grep "tiny_next_read" | wc -l || echo "0")
|
|
if [ ${DOUBLE_POP} -gt 0 ]; then
|
|
echo -e "${RED}❌ POTENTIAL BUG: Found ${DOUBLE_POP} sites with pop_lockfree + tiny_next_read${NC}"
|
|
echo " (slab_freelist_pop_lockfree already calls tiny_next_read internally!)"
|
|
grep -A1 "slab_freelist_pop_lockfree" core/ -r --include="*.c" --include="*.h" 2>/dev/null | grep -B1 "tiny_next_read"
|
|
else
|
|
echo -e "${GREEN}✅ No double-POP bugs detected${NC}"
|
|
fi
|
|
|
|
# Check for double PUSH (tiny_next_write + push)
|
|
DOUBLE_PUSH=$(grep -B1 "slab_freelist_push_lockfree" core/ -r --include="*.c" --include="*.h" 2>/dev/null | grep "tiny_next_write" | wc -l || echo "0")
|
|
if [ ${DOUBLE_PUSH} -gt 0 ]; then
|
|
echo -e "${RED}❌ POTENTIAL BUG: Found ${DOUBLE_PUSH} sites with tiny_next_write + push_lockfree${NC}"
|
|
echo " (slab_freelist_push_lockfree already calls tiny_next_write internally!)"
|
|
grep -B1 "slab_freelist_push_lockfree" core/ -r --include="*.c" --include="*.h" 2>/dev/null | grep "tiny_next_write"
|
|
else
|
|
echo -e "${GREEN}✅ No double-PUSH bugs detected${NC}"
|
|
fi
|
|
|
|
# Check for missing NULL checks after POP
|
|
MISSING_NULL_CHECK=$(grep -A3 "slab_freelist_pop_lockfree" core/ -r --include="*.c" --include="*.h" 2>/dev/null | grep -B3 -A3 "slab_freelist_pop_lockfree" | grep -v "if.*!.*block\|if.*block.*==.*NULL\|if.*!.*p\|if.*p.*==.*NULL" | grep "slab_freelist_pop_lockfree" | wc -l || echo "0")
|
|
# This is a heuristic check - may have false positives
|
|
if [ ${MISSING_NULL_CHECK} -gt 0 ]; then
|
|
echo -e "${YELLOW}⚠️ POTENTIAL ISSUE: ${MISSING_NULL_CHECK} POP sites may be missing NULL check${NC}"
|
|
echo " (Manual review recommended - this is a heuristic check)"
|
|
else
|
|
echo -e "${GREEN}✅ All POP operations appear to have NULL checks${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Compile check
|
|
echo "=== COMPILE CHECK ==="
|
|
if make bench_random_mixed_hakmem 2>&1 | grep -i "error" > /dev/null; then
|
|
echo -e "${RED}❌ Compilation FAILED${NC}"
|
|
echo " Run: make bench_random_mixed_hakmem 2>&1 | grep -i error"
|
|
else
|
|
echo -e "${GREEN}✅ Compilation succeeded${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Test binary check
|
|
echo "=== TEST BINARY CHECK ==="
|
|
if [ -f "out/release/bench_random_mixed_hakmem" ]; then
|
|
echo -e "${GREEN}✅ out/release/bench_random_mixed_hakmem exists${NC}"
|
|
|
|
# Check modification time (is it recent?)
|
|
MTIME=$(stat -c %Y out/release/bench_random_mixed_hakmem 2>/dev/null || stat -f %m out/release/bench_random_mixed_hakmem)
|
|
NOW=$(date +%s)
|
|
AGE=$((NOW - MTIME))
|
|
if [ ${AGE} -lt 3600 ]; then
|
|
echo -e "${GREEN}✅ Binary is recent (${AGE} seconds old)${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Binary is old (${AGE} seconds). Consider rebuilding.${NC}"
|
|
fi
|
|
else
|
|
echo -e "${YELLOW}⚠️ out/release/bench_random_mixed_hakmem not found. Run: make bench_random_mixed_hakmem${NC}"
|
|
fi
|
|
|
|
if [ -f "out/release/larson_hakmem" ]; then
|
|
echo -e "${GREEN}✅ out/release/larson_hakmem exists${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ out/release/larson_hakmem not found. Run: make larson_hakmem${NC}"
|
|
fi
|
|
echo ""
|
|
|
|
# Recommendations
|
|
echo "=== RECOMMENDATIONS ==="
|
|
|
|
if [ ${PROGRESS} -eq 0 ]; then
|
|
echo "1. Create accessor header:"
|
|
echo " cp core/box/slab_freelist_atomic.h.TEMPLATE core/box/slab_freelist_atomic.h"
|
|
echo ""
|
|
echo "2. Start Phase 1 conversion (5 files, 25 sites):"
|
|
echo " See ATOMIC_FREELIST_SITE_BY_SITE_GUIDE.md"
|
|
elif [ ${PROGRESS} -lt 30 ]; then
|
|
echo "Phase 1 in progress..."
|
|
echo "1. Continue converting Phase 1 files (${PHASE1_DONE}/4 done)"
|
|
echo "2. Test after each file: make bench_random_mixed_hakmem"
|
|
echo "3. Phase 1 final test: ./out/release/larson_hakmem 8 100000 256"
|
|
elif [ ${PROGRESS} -lt 60 ]; then
|
|
echo "Phase 1 likely complete, start Phase 2..."
|
|
echo "1. Test Phase 1 results: ./out/release/larson_hakmem 8 100000 256"
|
|
echo "2. Start Phase 2 conversion (10 files, 40 sites)"
|
|
echo "3. See ATOMIC_FREELIST_SITE_BY_SITE_GUIDE.md for Phase 2 files"
|
|
elif [ ${PROGRESS} -lt 90 ]; then
|
|
echo "Phase 2 in progress, prepare for Phase 3..."
|
|
echo "1. Test Phase 2 results: for t in 1 2 4 8; do ./out/release/larson_hakmem \$t 100000 256; done"
|
|
echo "2. Start Phase 3 cleanup (5 files, 25 sites)"
|
|
echo "3. Focus on debug/stats sites (use SLAB_FREELIST_DEBUG_PTR)"
|
|
else
|
|
echo "Nearly complete! Final verification..."
|
|
echo "1. Run full test suite: ./run_all_tests.sh"
|
|
echo "2. Check for remaining direct accesses: grep -rn 'meta->freelist' core/"
|
|
echo "3. ASan/TSan tests: ./build.sh tsan larson_hakmem"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Summary
|
|
echo "=== SUMMARY ==="
|
|
echo "Baseline total sites: ${BASELINE_TOTAL}"
|
|
echo "Converted sites: ${TOTAL_CONVERTED}"
|
|
echo "Remaining sites: $((BASELINE_TOTAL - TOTAL_CONVERTED))"
|
|
echo "Progress: ${PROGRESS}%"
|
|
echo ""
|
|
|
|
if [ ${PROGRESS} -ge 100 ]; then
|
|
echo -e "${GREEN}🎉 CONVERSION COMPLETE! 🎉${NC}"
|
|
echo ""
|
|
echo "Final checklist:"
|
|
echo "[ ] All tests pass"
|
|
echo "[ ] No ASan/TSan warnings"
|
|
echo "[ ] Performance regression <3%"
|
|
echo "[ ] Larson 8T stable"
|
|
echo "[ ] Documentation updated (CLAUDE.md)"
|
|
else
|
|
PHASE=""
|
|
if [ ${PROGRESS} -lt 30 ]; then
|
|
PHASE="Phase 1 (Critical Hot Paths)"
|
|
elif [ ${PROGRESS} -lt 60 ]; then
|
|
PHASE="Phase 2 (Important Paths)"
|
|
else
|
|
PHASE="Phase 3 (Cleanup)"
|
|
fi
|
|
echo -e "${BLUE}Currently working on: ${PHASE}${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo "========================================"
|
|
echo "Verification Complete"
|
|
echo "========================================"
|