QtxAcqHistTracker: Add spinlock and use it
This commit is contained in:
@@ -66,7 +66,6 @@ bool QutexAcquisitionHistoryTracker
|
||||
::heuristicallyTraceContinuationHistoryForGridlockOn(
|
||||
Qutex &firstFailedQutex,
|
||||
std::shared_ptr<AsynchronousContinuationChainLink>& currentContinuation)
|
||||
const
|
||||
{
|
||||
/** HEURISTIC APPROACH:
|
||||
* Due to the computational complexity of full circularity detection,
|
||||
@@ -82,6 +81,28 @@ const
|
||||
* explanation.
|
||||
*/
|
||||
|
||||
/** NOTICE:
|
||||
* Generally we should have all global data structures owned by a single
|
||||
* ComponentThread; and qutexes really should only be used to serialize
|
||||
* async sequences being enqueued on the same ComponentThread. But this
|
||||
* doesn't prevent multiple CPUs from trying to add/remove entries to/from
|
||||
* the acquisition history at the same time. Why? The acquisition history
|
||||
* isn't per-CPU, it's global.
|
||||
*
|
||||
* The problem with using a SpinLock here is that if the STL uses mutexes
|
||||
* internally to lock containers, we could end up in a situation where
|
||||
* spinning waiters will be busy-spinning while the owner is sleeping?
|
||||
*
|
||||
* But this should not happen since the nature of the order of operations is
|
||||
* that the spinlock ensures that only one CPU at a time can be
|
||||
* adding/removing entries; and thus everytime an method is called on the
|
||||
* unordered_map, the caller will always succeed at acquiring the underlying
|
||||
* STL mutex.
|
||||
*
|
||||
* So it should be safe to use a SpinLock here.
|
||||
*/
|
||||
acquisitionHistoryLock.acquire();
|
||||
|
||||
// Iterate through all entries in the acquisition history
|
||||
for (const auto& entry : acquisitionHistory) {
|
||||
const auto& continuation = entry.first;
|
||||
@@ -104,18 +125,20 @@ const
|
||||
/* Found firstFailedQutex in another continuation's held locks
|
||||
* This indicates a potential gridlock
|
||||
*/
|
||||
if (&heldLock.get() == &firstFailedQutex) {
|
||||
if (&heldLock.get() == &firstFailedQutex)
|
||||
{
|
||||
acquisitionHistoryLock.release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acquisitionHistoryLock.release();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QutexAcquisitionHistoryTracker
|
||||
::completelyTraceContinuationHistoryForGridlockOn(Qutex &firstFailedQutex)
|
||||
const
|
||||
{
|
||||
/** ALGORITHMICALLY COMPLETE VERSION:
|
||||
* This function is intended to implement the algorithmically complete
|
||||
@@ -128,6 +151,9 @@ const
|
||||
* explanation.
|
||||
*/
|
||||
|
||||
// acquisitionHistoryLock.acquire();
|
||||
// TODO: Implement full circularity detection algorithm
|
||||
// acquisitionHistoryLock.release();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user