GroveEngine/diagram_dev_workflow.html
StillHammer aefd7921b2 fix: Critical race conditions in ThreadedModuleSystem and logger
Fixed two critical race conditions that prevented multi-threaded module execution:

## Bug #1: ThreadedModuleSystem::registerModule() race condition

**Symptom:** Deadlock on first processModules() call
**Root Cause:** Worker thread started before being added to workers vector
**Fix:** Add worker to vector BEFORE spawning thread (src/ThreadedModuleSystem.cpp:102-108)

Before:
- Create worker → Start thread → Add to vector (RACE!)
- Thread accesses workers[index] before push_back completes

After:
- Create worker → Add to vector → Start thread (SAFE)
- Thread guaranteed to find worker in vector

## Bug #2: stillhammer::createLogger() race condition

**Symptom:** Deadlock when multiple threads create loggers simultaneously
**Root Cause:** Check-then-register pattern without mutex protection
**Fix:** Added static mutex around spdlog::get() + register_logger() (external/StillHammer/logger/src/Logger.cpp:94-96)

Before:
- Thread 1: check → create → register
- Thread 2: check → create → register (RACE on spdlog registry!)

After:
- Mutex protects entire check-then-register critical section

## Validation & Testing

Added comprehensive test suite:
- test_threaded_module_system.cpp (6 unit tests)
- test_threaded_stress.cpp (5 stress tests: 50 modules × 1000 frames)
- test_logger_threadsafe.cpp (concurrent logger creation)
- benchmark_threaded_vs_sequential.cpp (performance comparison)
- docs/THREADED_MODULE_SYSTEM_VALIDATION.md (full validation report)

All tests passing (100%):
- ThreadedModuleSystem:  0.15s
- ThreadedStress:  7.64s
- LoggerThreadSafe:  0.13s

## Impact

ThreadedModuleSystem now PRODUCTION READY:
- Thread-safe module registration
- Stable parallel execution (validated with 50,000+ operations)
- Hot-reload working (100 cycles tested)
- Logger thread-safe for concurrent module initialization

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 07:37:31 +07:00

339 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GroveEngine - Development Workflow</title>
<style>
body {
margin: 0;
padding: 20px;
background: #1a1a2e;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: 'Consolas', 'Monaco', monospace;
}
.diagram-container {
width: 1200px;
height: 800px;
background: white;
border-radius: 10px;
padding: 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
svg {
width: 100%;
height: 100%;
}
.step-box {
filter: drop-shadow(3px 3px 5px rgba(0,0,0,0.2));
}
.step-edit {
fill: #e1f5fe;
stroke: #0288d1;
stroke-width: 3;
}
.step-build {
fill: #fff3e0;
stroke: #f57c00;
stroke-width: 3;
}
.step-reload {
fill: #ffebee;
stroke: #d32f2f;
stroke-width: 3;
}
.step-test {
fill: #e8f5e9;
stroke: #388e3c;
stroke-width: 3;
}
.step-iterate {
fill: #f3e5f5;
stroke: #7b1fa2;
stroke-width: 3;
}
.arrow {
stroke: #424242;
stroke-width: 4;
fill: none;
marker-end: url(#arrowhead-large);
}
.arrow-fast {
stroke: #d32f2f;
stroke-width: 4;
fill: none;
marker-end: url(#arrowhead-fast);
}
.step-number {
font-size: 24px;
font-weight: bold;
fill: #fff;
}
.step-title {
font-size: 18px;
font-weight: bold;
fill: #1a1a1a;
}
.step-desc {
font-size: 11px;
fill: #555;
}
.timing-fast {
font-size: 16px;
font-weight: bold;
fill: #d32f2f;
}
.timing-normal {
font-size: 14px;
fill: #666;
}
.main-title {
font-size: 32px;
font-weight: bold;
fill: #1a1a1a;
}
.subtitle {
font-size: 14px;
fill: #666;
}
.metric-box {
fill: #f5f5f5;
stroke: #ddd;
stroke-width: 2;
}
.metric-value {
font-size: 28px;
font-weight: bold;
fill: #d32f2f;
}
.metric-label {
font-size: 11px;
fill: #666;
}
.comparison-box {
fill: #fff3e0;
stroke: #f57c00;
stroke-width: 2;
}
.comparison-title {
font-size: 14px;
font-weight: bold;
fill: #1a1a1a;
}
.comparison-text {
font-size: 11px;
fill: #555;
}
.icon {
font-size: 30px;
}
</style>
</head>
<body>
<div class="diagram-container">
<svg viewBox="0 0 1120 720" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrowhead-large" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto">
<polygon points="0 0, 12 4, 0 8" fill="#424242" />
</marker>
<marker id="arrowhead-fast" markerWidth="12" markerHeight="12" refX="10" refY="4" orient="auto">
<polygon points="0 0, 12 4, 0 8" fill="#d32f2f" />
</marker>
</defs>
<!-- Title -->
<text x="560" y="35" class="main-title" text-anchor="middle">GroveEngine Development Workflow</text>
<text x="560" y="55" class="subtitle" text-anchor="middle">Edit → Build → Hot-Reload Cycle • Total: &lt;1 second</text>
<!-- Step 1: Edit Code -->
<g class="step-box">
<rect x="50" y="120" width="180" height="120" rx="10" class="step-edit"/>
<circle cx="90" cy="150" r="20" fill="#0288d1"/>
<text x="90" y="159" class="step-number" text-anchor="middle">1</text>
<text class="icon" x="140" y="155" text-anchor="middle">✏️</text>
<text x="140" y="190" class="step-title" text-anchor="middle">Edit Code</text>
<text x="140" y="210" class="step-desc" text-anchor="middle">VSCode / IDE</text>
<text x="140" y="225" class="step-desc" text-anchor="middle">Modify module logic</text>
</g>
<!-- Arrow 1→2 -->
<path d="M 230 180 L 310 180" class="arrow"/>
<text x="270" y="170" class="timing-normal" text-anchor="middle">Save file</text>
<!-- Step 2: Build -->
<g class="step-box">
<rect x="310" y="120" width="180" height="120" rx="10" class="step-build"/>
<circle cx="350" cy="150" r="20" fill="#f57c00"/>
<text x="350" y="159" class="step-number" text-anchor="middle">2</text>
<text class="icon" x="400" y="155" text-anchor="middle">🔨</text>
<text x="400" y="190" class="step-title" text-anchor="middle">Build</text>
<text x="400" y="210" class="step-desc" text-anchor="middle">cmake --build build -j4</text>
<text x="400" y="225" class="timing-normal" text-anchor="middle">~300ms</text>
</g>
<!-- Arrow 2→3 (FAST) -->
<path d="M 490 180 L 570 180" class="arrow-fast"/>
<text x="530" y="170" class="timing-fast" text-anchor="middle">⚡ FAST</text>
<!-- Step 3: Hot-Reload -->
<g class="step-box">
<rect x="570" y="120" width="180" height="120" rx="10" class="step-reload"/>
<circle cx="610" cy="150" r="20" fill="#d32f2f"/>
<text x="610" y="159" class="step-number" text-anchor="middle">3</text>
<text class="icon" x="660" y="155" text-anchor="middle">🔥</text>
<text x="660" y="190" class="step-title" text-anchor="middle">Hot-Reload</text>
<text x="660" y="210" class="step-desc" text-anchor="middle">ModuleLoader.reload()</text>
<text x="660" y="225" class="timing-fast" text-anchor="middle">0.4ms avg</text>
</g>
<!-- Arrow 3→4 -->
<path d="M 660 240 L 660 310" class="arrow"/>
<text x="680" y="280" class="timing-normal">Instant</text>
<!-- Step 4: Test in Game -->
<g class="step-box">
<rect x="570" y="310" width="180" height="120" rx="10" class="step-test"/>
<circle cx="610" cy="340" r="20" fill="#388e3c"/>
<text x="610" y="349" class="step-number" text-anchor="middle">4</text>
<text class="icon" x="660" y="345" text-anchor="middle">🎮</text>
<text x="660" y="380" class="step-title" text-anchor="middle">Test in Game</text>
<text x="660" y="400" class="step-desc" text-anchor="middle">Game still running</text>
<text x="660" y="415" class="step-desc" text-anchor="middle">State preserved</text>
</g>
<!-- Arrow 4→5 -->
<path d="M 570 370 L 490 370" class="arrow"/>
<text x="530" y="390" class="timing-normal" text-anchor="middle">Evaluate</text>
<!-- Step 5: Iterate -->
<g class="step-box">
<rect x="310" y="310" width="180" height="120" rx="10" class="step-iterate"/>
<circle cx="350" cy="340" r="20" fill="#7b1fa2"/>
<text x="350" y="349" class="step-number" text-anchor="middle">5</text>
<text class="icon" x="400" y="345" text-anchor="middle">🔄</text>
<text x="400" y="380" class="step-title" text-anchor="middle">Iterate</text>
<text x="400" y="400" class="step-desc" text-anchor="middle">Need changes?</text>
<text x="400" y="415" class="step-desc" text-anchor="middle">Loop back to Step 1</text>
</g>
<!-- Arrow 5→1 (loop back) -->
<path d="M 310 370 Q 140 370 140 240" class="arrow"/>
<text x="200" y="310" class="timing-normal">Refine</text>
<!-- Arrow 5→Done (straight down) -->
<path d="M 400 430 L 400 480" class="arrow"/>
<text x="420" y="460" class="timing-normal">Done ✓</text>
<!-- Done box -->
<rect x="310" y="480" width="180" height="60" rx="10" fill="#c8e6c9" stroke="#388e3c" stroke-width="3"/>
<text x="400" y="510" class="step-title" text-anchor="middle" fill="#2e7d32">✓ Feature Complete</text>
<text x="400" y="528" class="step-desc" text-anchor="middle">Ship to production</text>
<!-- Metrics Panel -->
<rect x="800" y="120" width="280" height="140" rx="8" class="metric-box"/>
<text x="940" y="145" class="step-title" text-anchor="middle">Total Cycle Time</text>
<text x="940" y="190" class="metric-value" text-anchor="middle">&lt; 1s</text>
<text x="940" y="215" class="metric-label" text-anchor="middle">Edit → Test Complete</text>
<line x1="820" y1="230" x2="1060" y2="230" stroke="#ddd" stroke-width="2"/>
<text x="830" y="248" class="comparison-text">Breakdown:</text>
<text x="840" y="263" class="comparison-text">• Edit: instant</text>
<text x="840" y="278" class="comparison-text">• Build: ~300ms</text>
<text x="840" y="293" class="comparison-text" fill="#d32f2f" font-weight="bold">• Hot-Reload: 0.4ms ⚡</text>
<text x="840" y="308" class="comparison-text">• Test: instant</text>
<!-- Comparison with Traditional Workflow -->
<rect x="800" y="280" width="280" height="180" rx="8" class="comparison-box"/>
<text x="940" y="305" class="comparison-title" text-anchor="middle">vs. Traditional Workflow</text>
<text x="820" y="330" class="comparison-text" font-weight="bold">GroveEngine:</text>
<text x="830" y="345" class="comparison-text">1. Edit code</text>
<text x="830" y="360" class="comparison-text">2. Build (300ms)</text>
<text x="830" y="375" class="comparison-text" fill="#d32f2f" font-weight="bold">3. Hot-reload (0.4ms) ⚡</text>
<text x="830" y="390" class="comparison-text" fill="#388e3c" font-weight="bold">4. Test IMMEDIATELY ✓</text>
<text x="820" y="410" class="comparison-text" font-weight="bold">Traditional Engine:</text>
<text x="830" y="425" class="comparison-text">1. Edit code</text>
<text x="830" y="440" class="comparison-text">2. Build (5-30s) 😴</text>
<text x="830" y="455" class="comparison-text">3. Restart game (10-60s) 😴</text>
<!-- Hot-Reload Detail -->
<rect x="800" y="480" width="280" height="140" rx="8" fill="#ffebee" stroke="#d32f2f" stroke-width="2"/>
<text x="940" y="505" class="comparison-title" text-anchor="middle">Hot-Reload Breakdown (0.4ms)</text>
<text x="820" y="530" class="comparison-text">1. Extract state → 0.1ms</text>
<text x="820" y="545" class="comparison-text">2. Unload old .so → 0.05ms</text>
<text x="820" y="560" class="comparison-text">3. Load new .so → 0.15ms</text>
<text x="820" y="575" class="comparison-text">4. Restore state → 0.1ms</text>
<text x="940" y="600" class="metric-label" text-anchor="middle" fill="#d32f2f" font-weight="bold">
100% state preservation • Game keeps running
</text>
<!-- Benefits -->
<rect x="50" y="480" width="230" height="140" rx="8" fill="#e3f2fd" stroke="#2196f3" stroke-width="2"/>
<text x="165" y="505" class="comparison-title" text-anchor="middle">🚀 Benefits</text>
<text x="65" y="530" class="comparison-text">✓ Instant feedback loop</text>
<text x="65" y="545" class="comparison-text">✓ No context switching</text>
<text x="65" y="560" class="comparison-text">✓ No restart delays</text>
<text x="65" y="575" class="comparison-text">✓ Flow state maintained</text>
<text x="65" y="590" class="comparison-text">✓ 10-100x faster iteration</text>
<text x="65" y="605" class="comparison-text">✓ Perfect for experimentation</text>
<!-- Footer -->
<text x="560" y="650" class="subtitle" text-anchor="middle">
GroveEngine enables rapid prototyping with sub-second iteration cycles
</text>
<text x="560" y="680" class="comparison-text" text-anchor="middle">
Traditional: 15-90 seconds/iteration • GroveEngine: &lt;1 second/iteration • 15-90x faster! 🔥
</text>
<text x="560" y="710" class="comparison-text" text-anchor="middle" fill="#999">
GroveEngine © 2025 StillHammer • Optimized for AI-assisted rapid development
</text>
</svg>
</div>
</body>
</html>