#!/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 "========================================"