Create comprehensive prompt for successor developer/agent to implement the 15h deadlock detection & prevention plan. Includes: - Complete implementation roadmap (Semaine 1: Detection, Semaine 2: Prevention) - Step-by-step commands for each phase - Code examples BEFORE/AFTER - Success criteria and validation checklist - Debugging tips and common pitfalls - Final report template This prompt is fully autonomous - a fresh developer can execute the entire plan following this guide. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
17 KiB
Prompt : Implémentation du Plan Deadlock Detection & Prevention
Pour : Claude Code (successeur) ou développeur qui reprend ce plan Plan associé : PLAN_deadlock_detection_prevention.md Durée estimée : 15h sur 2 semaines Dernière mise à jour : 2025-01-21
🎯 Mission
Tu dois implémenter un système complet de détection et prévention des deadlocks pour GroveEngine, un moteur de jeu avec hot-reload de modules dynamiques en C++17.
Contexte :
- GroveEngine utilise actuellement
std::mutexavecstd::lock_guard - Pattern : Single mutex par classe (risque faible mais amélioration nécessaire)
- Un deadlock a été identifié dans
test_13_cross_system(teste encore bloqué) - Le projet compile sur Linux/WSL2 avec CMake
Objectif final :
- ✅ Détection automatique des deadlocks (TSan + Helgrind)
- ✅ Prévention des deadlocks multi-mutex (scoped_lock)
- ✅ Optimisation concurrence read-heavy (shared_mutex)
- ✅ Tous les tests passent sans deadlock
📚 Documentation Requise
IMPORTANT : Lis ces documents avant de commencer :
-
Plan complet :
docs/plans/PLAN_deadlock_detection_prevention.md- Contient TOUTES les modifications ligne par ligne
- Exemples de code AVANT/APRÈS
- Commandes exactes à exécuter
-
Tests d'intégration :
docs/plans/PLAN_integration_tests_global.md- Liste des 13 tests à valider
- Seuils de succès
-
Architecture :
docs/architecture/- Comprendre IntraIO, IntraIOManager, TopicTree
- Flux de messages pub/sub
🗓️ Calendrier d'Implémentation
Semaine 1 : Détection (5h)
Jour 1-2 : ThreadSanitizer (2h)
Checklist :
- Modifier
CMakeLists.txt(copier le code du plan lignes 21-35) - Build avec TSan :
cmake -DGROVE_ENABLE_TSAN=ON -B build-tsan - Exécuter tous les tests :
cd build-tsan && TSAN_OPTIONS="detect_deadlocks=1" ctest -V - Documenter les warnings TSan trouvés (créer
docs/tsan_findings.md) - Fixer tous les lock-order-inversions détectés
- Re-run tests jusqu'à 0 warning
Commandes :
# 1. Modifier CMakeLists.txt (copier du plan)
nano CMakeLists.txt
# 2. Build
cmake -DGROVE_ENABLE_TSAN=ON -B build-tsan
cmake --build build-tsan -j$(nproc)
# 3. Test
cd build-tsan
TSAN_OPTIONS="detect_deadlocks=1 history_size=7 exitcode=1" ctest --output-on-failure
# 4. Si erreurs, voir logs
cat Testing/Temporary/LastTest.log
Critères de succès :
- ✅ Build TSan compile sans erreurs
- ✅
ctestretourne exit code 0 - ✅ Aucun warning "lock-order-inversion"
- ✅ Aucun warning "data race"
Jour 3-4 : Helgrind (3h)
Checklist :
- Modifier
CMakeLists.txt(copier code du plan lignes 84-126) - Créer
helgrind.supp(copier du plan lignes 128-158) - Build :
cmake -DGROVE_ENABLE_HELGRIND=ON -B build - Exécuter :
cd build && make helgrind - Analyser
helgrind-full.log - Ajouter suppressions pour false positives
- Re-run jusqu'à log propre
- Créer tableau comparatif TSan vs Helgrind
Commandes :
# 1. Créer helgrind.supp (copier du plan)
nano helgrind.supp
# 2. Modifier CMakeLists.txt
nano CMakeLists.txt
# 3. Build
cmake -DGROVE_ENABLE_HELGRIND=ON -B build
cmake --build build
# 4. Run Helgrind (LENT - 10-50x slowdown)
cd build
make helgrind
# 5. Analyser résultats
cat helgrind-full.log | grep -E "(Possible|lock order)" | less
# 6. Compter problèmes
cat helgrind-full.log | grep "Possible data race" | wc -l
Critères de succès :
- ✅ Target
make helgrindfonctionne - ✅ Fichier helgrind.supp avec suppressions
- ✅ 0 lock order violations (après suppressions légitimes)
- ✅ Tableau comparatif TSan vs Helgrind documenté
Semaine 2 : Prévention & Optimisation (10h)
Jour 5-7 : std::scoped_lock (4h)
Checklist :
- Rechercher tous les lock_guard multi-mutex :
grep -n "lock_guard" src/*.cpp | sort - Identifier les patterns : lock(mutex1) puis lock(mutex2) dans même fonction
- Refactorer
IntraIOManager.cpplignes 176, 221, 256, 272, 329 - Remplacer par
std::scoped_lock(mutex1, mutex2) - Créer test unitaire
tests/unit/test_scoped_lock.cpp(copier du plan) - Build et tester :
cmake --build build && ctest - Valider avec TSan : aucun lock-order-inversion
Exemple de refactoring :
AVANT (src/IntraIOManager.cpp:176) :
void IntraIOManager::routeMessage(...) {
std::lock_guard<std::mutex> lock(managerMutex);
// ... code ...
std::lock_guard<std::mutex> batchLock(batchMutex); // ❌ Risque deadlock
}
APRÈS :
void IntraIOManager::routeMessage(...) {
std::scoped_lock lock(managerMutex, batchMutex); // ✅ Safe
// ... code ...
}
Fichiers à modifier :
src/IntraIOManager.cpp(5 endroits - voir plan lignes 213-234)tests/unit/test_scoped_lock.cpp(créer nouveau fichier - code dans plan lignes 236-283)docs/coding_guidelines.md(créer section - plan lignes 287-324)
Commandes :
# 1. Trouver tous les multi-mutex locks
grep -B3 -A3 "lock_guard" src/IntraIOManager.cpp
# 2. Modifier les fichiers (utilise ton éditeur)
nano src/IntraIOManager.cpp
# 3. Build et test
cmake --build build
ctest --output-on-failure
# 4. Validation TSan
cd build-tsan
cmake --build .
TSAN_OPTIONS="detect_deadlocks=1" ctest -V
Critères de succès :
- ✅ Tous les lock_guard multi-mutex remplacés
- ✅ Test
test_scoped_lockpasse - ✅ TSan validation : 0 lock-order-inversion
- ✅ Documentation coding_guidelines.md créée
Jour 8-10 : std::shared_mutex (6h)
Checklist - TopicTree :
- Modifier
external/StillHammer/topictree/include/topictree/TopicTree.hligne 56 - Changer
std::mutex→std::shared_mutex - Refactorer toutes les méthodes (voir plan lignes 406-478)
findSubscribers()→std::shared_lock(READ)registerSubscriber()→std::unique_lock(WRITE)unregisterSubscriber()→std::unique_lock(WRITE)clear()→std::unique_lock(WRITE)subscriberCount()→std::shared_lock(READ)
Checklist - IntraIOManager :
- Modifier
include/grove/IntraIOManager.h - Split
managerMutexen 2 :instancesMutex(shared) +statsMutex(exclusive) - Refactorer
src/IntraIOManager.cpp(voir plan lignes 480-594)getInstance()→std::shared_lock(READ)routeMessage()→std::shared_lockpour lookup (CRITICAL!)createInstance()→std::unique_lock(WRITE)removeInstance()→std::unique_lock(WRITE)
Checklist - JsonDataTree (optionnel) :
- Modifier
include/grove/JsonDataTree.hetsrc/JsonDataTree.cpp - Changer
std::mutex→std::shared_mutex - Refactorer méthodes (voir plan lignes 596-637)
Checklist - Benchmark :
- Créer
tests/benchmarks/benchmark_shared_mutex.cpp(plan lignes 641-688) - Ajouter au CMakeLists.txt (plan lignes 690-698)
- Build :
cmake --build build - Run :
./build/tests/benchmark_shared_mutex --benchmark_min_time=3s - Créer rapport
docs/performance_reports/shared_mutex_results.md(plan lignes 718-772)
Commandes :
# 1. Modifier TopicTree.h
nano external/StillHammer/topictree/include/topictree/TopicTree.h
# 2. Modifier IntraIOManager
nano include/grove/IntraIOManager.h
nano src/IntraIOManager.cpp
# 3. Modifier JsonDataTree (optionnel)
nano include/grove/JsonDataTree.h
nano src/JsonDataTree.cpp
# 4. Créer benchmark
mkdir -p tests/benchmarks
nano tests/benchmarks/benchmark_shared_mutex.cpp
# 5. Modifier CMakeLists.txt pour benchmark
nano tests/CMakeLists.txt
# 6. Build
cmake --build build -j$(nproc)
# 7. Run tests
ctest --output-on-failure
# 8. Validation TSan (CRITIQUE!)
cd build-tsan
cmake --build .
TSAN_OPTIONS="detect_deadlocks=1" ctest -V
# 9. Run benchmark
cd ../build
./tests/benchmark_shared_mutex --benchmark_min_time=3s
# 10. Créer rapport de performance
mkdir -p docs/performance_reports
nano docs/performance_reports/shared_mutex_results.md
Résultats attendus du benchmark :
1 thread: Overhead négligeable (~1%)
4 threads: Speedup 30-50x (mutex: 960ns → shared: 22ns)
8 threads: Speedup 150-250x (mutex: 7680ns → shared: 30ns)
Critères de succès :
- ✅ TopicTree utilise
shared_mutex - ✅ IntraIOManager split mutex (instances shared + stats exclusive)
- ✅ JsonDataTree utilise
shared_mutex(optionnel) - ✅ Benchmark créé et exécuté
- ✅ Rapport de performance rempli (gain >50% démontré)
- ✅ TSan validation : 0 data race
- ✅ Tous les tests d'intégration passent
🔧 Outils et Commandes Essentielles
Build Variants
# Normal build
cmake -B build && cmake --build build
# TSan build (détection deadlock)
cmake -DGROVE_ENABLE_TSAN=ON -B build-tsan
cmake --build build-tsan
# Helgrind build
cmake -DGROVE_ENABLE_HELGRIND=ON -B build
cmake --build build
cd build && make helgrind
Tests
# Tous les tests
ctest --output-on-failure
# Test spécifique
./tests/test_13_cross_system
# Avec TSan
TSAN_OPTIONS="detect_deadlocks=1 history_size=7" ./tests/test_13_cross_system
# Avec timeout (si deadlock)
timeout 30 ./tests/test_13_cross_system || echo "DEADLOCK DETECTED"
Debugging
# Voir les mutex actifs
ps aux | grep test_13
pstack <PID> # Si disponible
# Logs TSan détaillés
TSAN_OPTIONS="detect_deadlocks=1 verbosity=2 log_path=tsan.log" ./test_13
# Analyser Helgrind
cat helgrind-full.log | grep -A10 "lock order"
⚠️ Pièges à Éviter
1. Test 13 Deadlock (ligne 333)
Problème identifié :
// test_13_cross_system.cpp:331-333
auto dataRootPtr = tree->getDataRootReadOnly(); // ❌ Raw pointer
dataRootPtr->setChild("player", ...); // ❌ Modification via read-only!
Fix :
auto dataRoot = tree->getDataRoot(); // ✅ Writable unique_ptr
dataRoot->setChild("player", std::move(player5));
2. TSan False Positives
Si TSan rapporte des races sur :
spdlog: Ajouter à suppressions (lazy init benign)std::atomic: Normal, TSan ne comprend pas toujours- Thread creation/join : Benign
Ne supprime PAS :
- Lock-order-inversion : VRAI problème!
- Data race sur variables non-atomic : VRAI problème!
3. Helgrind Lenteur
- 10-50x slowdown est NORMAL
- Test complet peut prendre 1-2h
- Utilise
make helgrind-singlepour tester un seul test - Patience!
4. shared_mutex Performance
- Vérifie le ratio Read/Write : doit être >10:1
- Si writes fréquents (>30%), shared_mutex est PLUS LENT
- TopicTree : OK (100:1 ratio)
- IntraIOManager : OK (50:1 ratio)
- Stats counters : NON (1:1 ratio) → garde std::mutex
📋 Checklist Finale de Validation
Avant de considérer le plan terminé, vérifie :
Phase 1 : Détection
- CMakeLists.txt avec options GROVE_ENABLE_TSAN et GROVE_ENABLE_HELGRIND
- Build TSan compile et tests passent (exit code 0)
- Build Helgrind targets fonctionnent (
make helgrind) - Fichier helgrind.supp avec suppressions appropriées
- 0 lock-order-inversion dans TSan output
- 0 data race dans TSan output
- Documentation TSan vs Helgrind (tableau comparatif)
Phase 2 : Prévention
- Tous les lock_guard multi-mutex → scoped_lock
- Test unitaire test_scoped_lock.cpp passe
- Documentation coding_guidelines.md mise à jour
- TSan validation : 0 warning
Phase 3 : Optimisation
- TopicTree.h utilise std::shared_mutex
- IntraIOManager split instancesMutex (shared) + statsMutex (exclusive)
- JsonDataTree utilise std::shared_mutex (si applicable)
- Benchmark benchmark_shared_mutex créé et exécuté
- Rapport de performance avec gains >50% documenté
- TSan validation : 0 data race
- Tous les 13 tests d'intégration passent
Tests Critiques
- test_01_production_hotreload : PASS
- test_02_chaos_monkey : PASS
- test_03_stress_test : PASS (10 min)
- test_04_race_condition : PASS
- test_13_cross_system : PASS (fix deadlock ligne 333)
Documentation
- docs/tsan_findings.md créé
- docs/coding_guidelines.md mis à jour
- docs/performance_reports/shared_mutex_results.md créé
- README.md des plans mis à jour (statut 🟢)
🎯 Critères de Succès Final
Le plan est TERMINÉ quand :
-
✅ Build TSan :
cmake -DGROVE_ENABLE_TSAN=ON -B build-tsan && cd build-tsan && TSAN_OPTIONS="detect_deadlocks=1" ctest- Exit code: 0
- Output: "100% tests passed, 0 tests failed"
- Aucun warning TSan
-
✅ Build Helgrind :
cd build && make helgrind- Exit code: 0
- helgrind-full.log propre (après suppressions)
-
✅ Tests d'intégration :
ctest --output-on-failure- 13/13 tests passent
- Dont test_13_cross_system (fix deadlock)
-
✅ Benchmark :
./tests/benchmark_shared_mutex- Speedup >50% démontré (4 threads)
- Rapport de performance documenté
-
✅ Code Review :
- Aucun lock_guard multi-mutex restant
- Tous les read-heavy locks sont shared_lock
- Tous les write locks sont unique_lock
📞 En Cas de Problème
Test 13 deadlock toujours présent
# 1. Identifier où ça bloque
timeout 10 ./tests/test_13_cross_system
ps aux | grep test_13
pstack <PID> # Voir les stacks
# 2. Vérifier le fix ligne 333
grep -n "getDataRootReadOnly" tests/integration/test_13_cross_system.cpp
# Doit utiliser getDataRoot() au lieu de getDataRootReadOnly()
# 3. Rebuild et retest
cmake --build build
./tests/test_13_cross_system
TSan trouve encore des lock-order-inversions
# 1. Voir exactement où
TSAN_OPTIONS="detect_deadlocks=1 history_size=7 second_deadlock_stack=1" ./problematic_test
# 2. Identifier les mutexes (M1, M2)
# 3. Utiliser scoped_lock(M1, M2) partout
# 4. Rebuild et retest
Helgrind timeout
# 1. Run un seul test
make helgrind-single
# 2. Si trop lent, skip Helgrind
# TSan est suffisant pour validation
Benchmark ne montre pas de gain
# 1. Vérifier le ratio read/write
# Si writes > 30%, shared_mutex est inutile
# 2. Vérifier que tu as bien utilisé shared_lock pour les reads
grep "shared_lock" src/IntraIOManager.cpp
# 3. Run benchmark avec plus de threads
./benchmark_shared_mutex --benchmark_filter=.*MultiThread.*/threads:8
📝 Rapport Final à Produire
Quand tout est terminé, crée : docs/plans/REPORT_deadlock_plan_completed.md
Template :
# Rapport : Plan Deadlock Detection & Prevention - TERMINÉ
**Date de complétion** : YYYY-MM-DD
**Durée réelle** : Xh (estimé: 15h)
**Statut** : ✅ TERMINÉ
## Résumé
[1-2 paragraphes résumant ce qui a été fait]
## Phase 1 : Détection (5h)
- ✅ ThreadSanitizer intégré (2h réelles)
- Warnings TSan trouvés : X
- Fixes appliqués : Y
- ✅ Helgrind intégré (3h réelles)
- Suppressions ajoutées : Z
## Phase 2 : Prévention (4h)
- ✅ scoped_lock refactoring (4h réelles)
- Fichiers modifiés : X
- Lock_guard → scoped_lock : Y endroits
## Phase 3 : Optimisation (6h)
- ✅ shared_mutex implémenté (6h réelles)
- TopicTree : ✅
- IntraIOManager : ✅
- JsonDataTree : ✅/❌
- Speedup mesuré : Xx (4 threads), Yy (8 threads)
## Tests Validation
| Test | Avant | Après | Statut |
|------|-------|-------|--------|
| test_01 | ✅ | ✅ | OK |
| test_02 | ✅ | ✅ | OK |
| ... | ... | ... | ... |
| test_13 | ❌ Deadlock | ✅ | FIXED |
## Benchmark Results
[Copier les résultats du benchmark]
## Problèmes Rencontrés
1. [Problème 1 et solution]
2. [Problème 2 et solution]
## Leçons Apprises
[Ce qui a été appris pendant l'implémentation]
## Recommandations Futures
1. [Amélioration 1]
2. [Amélioration 2]
🚀 Let's Go!
Tu as maintenant TOUT ce qu'il faut :
- ✅ Plan détaillé (30KB de specs)
- ✅ Code AVANT/APRÈS ligne par ligne
- ✅ Commandes exactes
- ✅ Tests de validation
- ✅ Debugging tips
- ✅ Checklist complète
Commence par la Phase 1.1 (ThreadSanitizer - 2h) :
# 1. Ouvre le plan
cat docs/plans/PLAN_deadlock_detection_prevention.md
# 2. Copie le code CMake (lignes 21-35)
nano CMakeLists.txt
# 3. Build
cmake -DGROVE_ENABLE_TSAN=ON -B build-tsan
cmake --build build-tsan
# 4. Test
cd build-tsan
TSAN_OPTIONS="detect_deadlocks=1" ctest -V
# 5. Fix tous les warnings
# 6. Re-test jusqu'à 0 warning
Bonne chance ! 🎯
Auteur : Claude Code Version : 1.0 Pour : Successeur/Implémenteur du plan deadlock Date : 2025-01-21