GroveEngine/groveengine_diagram.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

302 lines
14 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 Architecture Diagram</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%;
}
.box {
stroke-width: 2;
filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.2));
}
.app-box {
fill: #e8f5e9;
stroke: #4caf50;
}
.iio-box {
fill: #e3f2fd;
stroke: #2196f3;
}
.system-box {
fill: #fff3e0;
stroke: #ff9800;
}
.core-box {
fill: #f3e5f5;
stroke: #9c27b0;
}
.title-text {
font-size: 14px;
font-weight: bold;
fill: #1a1a1a;
}
.subtitle-text {
font-size: 11px;
fill: #666;
}
.detail-text {
font-size: 9px;
fill: #888;
}
.layer-label {
font-size: 11px;
font-weight: bold;
fill: #999;
text-transform: uppercase;
letter-spacing: 1px;
}
.arrow {
stroke: #666;
stroke-width: 2;
fill: none;
marker-end: url(#arrowhead);
}
.arrow-label {
font-size: 10px;
fill: #666;
font-weight: bold;
}
.main-title {
font-size: 28px;
font-weight: bold;
fill: #1a1a1a;
}
.badge {
fill: #2196f3;
stroke: none;
}
.badge-text {
fill: white;
font-size: 10px;
font-weight: bold;
}
.metric-label {
font-size: 10px;
fill: #666;
}
.metric-value {
font-size: 16px;
font-weight: bold;
fill: #2196f3;
}
</style>
</head>
<body>
<div class="diagram-container">
<svg viewBox="0 0 1120 720" xmlns="http://www.w3.org/2000/svg">
<!-- Definitions -->
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<polygon points="0 0, 10 3, 0 6" fill="#666" />
</marker>
</defs>
<!-- Title -->
<text x="560" y="30" class="main-title" text-anchor="middle">🌳 GroveEngine Architecture</text>
<!-- Badges -->
<rect x="380" y="40" width="120" height="20" rx="10" class="badge"/>
<text x="440" y="53" class="badge-text" text-anchor="middle">0.4ms Hot-Reload</text>
<rect x="510" y="40" width="100" height="20" rx="10" class="badge"/>
<text x="560" y="53" class="badge-text" text-anchor="middle">Experimental</text>
<rect x="620" y="40" width="120" height="20" rx="10" class="badge"/>
<text x="680" y="53" class="badge-text" text-anchor="middle">Dual License 1%</text>
<!-- Layer 1: Application -->
<text x="20" y="90" class="layer-label">Application Layer</text>
<!-- Game Logic Module -->
<rect x="20" y="100" width="200" height="80" rx="8" class="box app-box"/>
<text x="120" y="122" class="title-text" text-anchor="middle">Game Logic Module</text>
<text x="120" y="138" class="subtitle-text" text-anchor="middle">Your Custom Code</text>
<text x="30" y="155" class="detail-text">• 200-300 lines</text>
<text x="30" y="167" class="detail-text">• Pure business logic</text>
<!-- UI Module -->
<rect x="240" y="100" width="200" height="80" rx="8" class="box app-box"/>
<text x="340" y="122" class="title-text" text-anchor="middle">UIModule</text>
<text x="340" y="138" class="subtitle-text" text-anchor="middle">Phase 7 Complete</text>
<text x="250" y="155" class="detail-text">• 10 widget types</text>
<text x="250" y="167" class="detail-text">• Retained rendering</text>
<!-- Custom Modules -->
<rect x="460" y="100" width="200" height="80" rx="8" class="box app-box"/>
<text x="560" y="122" class="title-text" text-anchor="middle">Custom Modules</text>
<text x="560" y="138" class="subtitle-text" text-anchor="middle">Extensible</text>
<text x="470" y="155" class="detail-text">• AI, Physics, Audio...</text>
<text x="470" y="167" class="detail-text">• Hot-swappable</text>
<!-- Arrows from App to IIO -->
<line x1="120" y1="180" x2="120" y2="230" class="arrow"/>
<line x1="340" y1="180" x2="340" y2="230" class="arrow"/>
<line x1="560" y1="180" x2="560" y2="230" class="arrow"/>
<text x="340" y="210" class="arrow-label" text-anchor="middle">publish/subscribe</text>
<!-- Layer 2: IIO Pub/Sub -->
<text x="20" y="250" class="layer-label">IIO Messaging Layer</text>
<rect x="20" y="260" width="640" height="90" rx="8" class="box iio-box"/>
<text x="340" y="285" class="title-text" text-anchor="middle">IntraIOManager (TopicTree)</text>
<text x="340" y="303" class="subtitle-text" text-anchor="middle">Sub-millisecond Pub/Sub • Wildcard Patterns • Zero Coupling</text>
<text x="40" y="325" class="detail-text">Topics: render:*, ui:*, input:*, game:*</text>
<text x="40" y="337" class="detail-text">Pattern matching: O(k) where k = pattern depth</text>
<!-- Arrows from IIO to System -->
<line x1="120" y1="350" x2="120" y2="395" class="arrow"/>
<line x1="340" y1="350" x2="340" y2="395" class="arrow"/>
<line x1="560" y1="350" x2="560" y2="395" class="arrow"/>
<!-- Layer 3: System Modules -->
<text x="20" y="415" class="layer-label">System Modules Layer</text>
<!-- BgfxRenderer -->
<rect x="20" y="425" width="200" height="100" rx="8" class="box system-box"/>
<text x="120" y="447" class="title-text" text-anchor="middle">BgfxRenderer</text>
<text x="120" y="463" class="subtitle-text" text-anchor="middle">Phase 8 Complete</text>
<text x="30" y="480" class="detail-text">• Sprites + batching</text>
<text x="30" y="492" class="detail-text">• Tilemap + particles</text>
<text x="30" y="504" class="detail-text">• DX11/12, GL, Vulkan</text>
<text x="30" y="516" class="detail-text">• Multi-texture support</text>
<!-- InputModule -->
<rect x="240" y="425" width="200" height="100" rx="8" class="box system-box"/>
<text x="340" y="447" class="title-text" text-anchor="middle">InputModule</text>
<text x="340" y="463" class="subtitle-text" text-anchor="middle">Phase 1-3</text>
<text x="250" y="480" class="detail-text">• Mouse + Keyboard</text>
<text x="250" y="492" class="detail-text">• SDL2 backend</text>
<text x="250" y="504" class="detail-text">• Thread-safe buffer</text>
<text x="250" y="516" class="detail-text">• Gamepad: TODO</text>
<!-- NetworkIO -->
<rect x="460" y="425" width="200" height="100" rx="8" class="box system-box"/>
<text x="560" y="447" class="title-text" text-anchor="middle">NetworkIO</text>
<text x="560" y="463" class="subtitle-text" text-anchor="middle">TODO</text>
<text x="470" y="480" class="detail-text">• Distributed pub/sub</text>
<text x="470" y="492" class="detail-text">• Remote IPC</text>
<text x="470" y="504" class="detail-text">• Network transparency</text>
<!-- Arrows from System to Core -->
<line x1="120" y1="525" x2="120" y2="570" class="arrow"/>
<line x1="340" y1="525" x2="340" y2="570" class="arrow"/>
<line x1="560" y1="525" x2="560" y2="570" class="arrow"/>
<!-- Layer 4: Core Infrastructure -->
<text x="20" y="590" class="layer-label">Core Infrastructure</text>
<!-- ModuleLoader -->
<rect x="20" y="600" width="300" height="90" rx="8" class="box core-box"/>
<text x="170" y="622" class="title-text" text-anchor="middle">ModuleLoader + Hot-Reload</text>
<text x="170" y="638" class="subtitle-text" text-anchor="middle">Dynamic .so/.dll Loading</text>
<text x="30" y="655" class="detail-text">• 0.4ms average reload</text>
<text x="30" y="667" class="detail-text">• 0.055ms best time</text>
<text x="30" y="679" class="detail-text">• 100% state preservation</text>
<!-- SequentialModuleSystem -->
<rect x="340" y="600" width="320" height="90" rx="8" class="box core-box"/>
<text x="500" y="622" class="title-text" text-anchor="middle">SequentialModuleSystem</text>
<text x="500" y="638" class="subtitle-text" text-anchor="middle">Single-threaded Execution</text>
<text x="350" y="655" class="detail-text">• Deterministic order (current)</text>
<text x="350" y="667" class="detail-text">• Multi-threaded: TODO</text>
<text x="350" y="679" class="detail-text">• Factory pattern (swappable infra)</text>
<!-- Right panel: Metrics -->
<text x="720" y="90" class="layer-label">Key Metrics</text>
<!-- Metric 1 -->
<rect x="720" y="100" width="180" height="60" rx="8" fill="#f5f5f5" stroke="#ddd" stroke-width="2"/>
<text x="810" y="125" class="metric-value" text-anchor="middle">0.4ms</text>
<text x="810" y="150" class="metric-label" text-anchor="middle">Hot-Reload Average</text>
<!-- Metric 2 -->
<rect x="920" y="100" width="180" height="60" rx="8" fill="#f5f5f5" stroke="#ddd" stroke-width="2"/>
<text x="1010" y="125" class="metric-value" text-anchor="middle">20+</text>
<text x="1010" y="150" class="metric-label" text-anchor="middle">Integration Tests</text>
<!-- Metric 3 -->
<rect x="720" y="175" width="180" height="60" rx="8" fill="#f5f5f5" stroke="#ddd" stroke-width="2"/>
<text x="810" y="200" class="metric-value" text-anchor="middle">100%</text>
<text x="810" y="225" class="metric-label" text-anchor="middle">State Preserved</text>
<!-- Metric 4 -->
<rect x="920" y="175" width="180" height="60" rx="8" fill="#f5f5f5" stroke="#ddd" stroke-width="2"/>
<text x="1010" y="200" class="metric-value" text-anchor="middle">1%</text>
<text x="1010" y="225" class="metric-label" text-anchor="middle">Royalty Rate</text>
<!-- Status Box -->
<rect x="720" y="260" width="380" height="130" rx="8" fill="#fff3e0" stroke="#ff9800" stroke-width="2"/>
<text x="910" y="285" class="title-text" text-anchor="middle" fill="#e65100">⚠️ Development Stage</text>
<text x="730" y="310" class="detail-text" fill="#555">Status: Experimental, non-deterministic</text>
<text x="730" y="325" class="detail-text" fill="#555">Best for: Rapid prototyping, learning, experimentation</text>
<text x="730" y="340" class="detail-text" fill="#555">Not suitable for: Production games, networked apps</text>
<text x="730" y="360" class="detail-text" fill="#555">License: GPL v3 (free) / Commercial (1% royalty &gt; €100k)</text>
<text x="730" y="375" class="detail-text" fill="#555">Contact: alexistrouve.pro@gmail.com</text>
<!-- Technologies Box -->
<rect x="720" y="410" width="380" height="100" rx="8" fill="#e8f5e9" stroke="#4caf50" stroke-width="2"/>
<text x="910" y="435" class="title-text" text-anchor="middle" fill="#2e7d32">Technologies Stack</text>
<text x="730" y="455" class="detail-text">• C++17 • CMake 3.20+ • bgfx (rendering)</text>
<text x="730" y="470" class="detail-text">• SDL2 (input) • nlohmann/json • spdlog (logging)</text>
<text x="730" y="485" class="detail-text">• TopicTree (O(k) pattern matching)</text>
<text x="730" y="500" class="detail-text">• Platforms: Windows, Linux (macOS untested)</text>
<!-- Use Cases -->
<rect x="720" y="530" width="380" height="100" rx="8" fill="#e3f2fd" stroke="#2196f3" stroke-width="2"/>
<text x="910" y="555" class="title-text" text-anchor="middle" fill="#0d47a1">Perfect For</text>
<text x="730" y="575" class="detail-text">✓ Rapid game prototyping with instant iteration</text>
<text x="730" y="590" class="detail-text">✓ Learning modular architecture patterns</text>
<text x="730" y="605" class="detail-text">✓ AI-assisted development (Claude Code optimized)</text>
<text x="730" y="620" class="detail-text">✓ Testing game mechanics quickly (hot-reload)</text>
<!-- Footer -->
<text x="560" y="710" class="detail-text" text-anchor="middle" fill="#999">
GroveEngine © 2025 StillHammer • github.com/AlexisTrouve/GroveEngine
</text>
</svg>
</div>
</body>
</html>