QtxAcqHistTracker: implement heuristic gridlock detector

This commit is contained in:
2025-09-29 20:02:23 -04:00
parent d32cb1ddac
commit 2390042892
3 changed files with 39 additions and 4 deletions
+3 -1
View File
@@ -106,7 +106,9 @@ public:
} }
bool heuristicallyTraceContinuationHistoryForGridlockOn( bool heuristicallyTraceContinuationHistoryForGridlockOn(
Qutex &firstFailedQutex) const; Qutex &firstFailedQutex,
std::shared_ptr<AsynchronousContinuationChainLink>& currentContinuation)
const;
bool completelyTraceContinuationHistoryForGridlockOn( bool completelyTraceContinuationHistoryForGridlockOn(
Qutex &firstFailedQutex) const; Qutex &firstFailedQutex) const;
+5 -2
View File
@@ -134,13 +134,16 @@ public:
.getAcquiredQutexHistory(); .getAcquiredQutexHistory();
// Add this continuation to the tracker // Add this continuation to the tracker
auto currentContinuationShPtr = serializedContinuation
.shared_from_this();
tracker.addIfNotExists( tracker.addIfNotExists(
serializedContinuation.shared_from_this(), currentContinuationShPtr,
firstFailedQutex, std::move(heldLocks)); firstFailedQutex, std::move(heldLocks));
gridlockIsHeuristicallyLikely = tracker gridlockIsHeuristicallyLikely = tracker
.heuristicallyTraceContinuationHistoryForGridlockOn( .heuristicallyTraceContinuationHistoryForGridlockOn(
firstFailedQutex); firstFailedQutex, currentContinuationShPtr);
if (gridlockIsHeuristicallyLikely) if (gridlockIsHeuristicallyLikely)
{ {
+31 -1
View File
@@ -63,7 +63,9 @@ namespace smo {
*/ */
bool QutexAcquisitionHistoryTracker bool QutexAcquisitionHistoryTracker
::heuristicallyTraceContinuationHistoryForGridlockOn(Qutex &firstFailedQutex) ::heuristicallyTraceContinuationHistoryForGridlockOn(
Qutex &firstFailedQutex,
std::shared_ptr<AsynchronousContinuationChainLink>& currentContinuation)
const const
{ {
/** HEURISTIC APPROACH: /** HEURISTIC APPROACH:
@@ -80,6 +82,34 @@ const
* explanation. * explanation.
*/ */
// Iterate through all entries in the acquisition history
for (const auto& entry : acquisitionHistory) {
const auto& continuation = entry.first;
const auto& historyEntry = entry.second;
// Skip the current continuation (don't compare with itself)
if (continuation == currentContinuation) {
continue;
}
// Check if firstFailedQutex is in this continuation's held locks
const std::unique_ptr<std::forward_list<std::reference_wrapper<Qutex>>>&
heldLocks = historyEntry.second;
if (!heldLocks)
{ continue; }
for (const auto& heldLock : *heldLocks)
{
/* Found firstFailedQutex in another continuation's held locks
* This indicates a potential gridlock
*/
if (&heldLock.get() == &firstFailedQutex) {
return true;
}
}
}
return false; return false;
} }