QtxAcqHistTracker: Add spinlock and use it
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <memory>
|
||||
#include <forward_list>
|
||||
#include <functional>
|
||||
#include "spinLock.h"
|
||||
|
||||
|
||||
namespace smo {
|
||||
@@ -75,15 +76,20 @@ public:
|
||||
heldLocks
|
||||
)
|
||||
{
|
||||
auto it = acquisitionHistory.find(continuation);
|
||||
acquisitionHistoryLock.acquire();
|
||||
|
||||
auto it = acquisitionHistory.find(continuation);
|
||||
// If a continuation already exists, don't add it again
|
||||
if (it != acquisitionHistory.end()) {
|
||||
if (it != acquisitionHistory.end())
|
||||
{
|
||||
acquisitionHistoryLock.release();
|
||||
return;
|
||||
}
|
||||
|
||||
acquisitionHistory.emplace(continuation, std::make_pair(
|
||||
std::ref(wantedLock), std::move(heldLocks)));
|
||||
|
||||
acquisitionHistoryLock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,20 +103,27 @@ public:
|
||||
std::shared_ptr<AsynchronousContinuationChainLink> &continuation
|
||||
)
|
||||
{
|
||||
acquisitionHistoryLock.acquire();
|
||||
|
||||
auto it = acquisitionHistory.find(continuation);
|
||||
if (it != acquisitionHistory.end()) {
|
||||
if (it != acquisitionHistory.end())
|
||||
{
|
||||
acquisitionHistory.erase(it);
|
||||
|
||||
acquisitionHistoryLock.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
acquisitionHistoryLock.release();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool heuristicallyTraceContinuationHistoryForGridlockOn(
|
||||
Qutex &firstFailedQutex,
|
||||
std::shared_ptr<AsynchronousContinuationChainLink>& currentContinuation)
|
||||
const;
|
||||
std::shared_ptr<AsynchronousContinuationChainLink>&
|
||||
currentContinuation);
|
||||
bool completelyTraceContinuationHistoryForGridlockOn(
|
||||
Qutex &firstFailedQutex) const;
|
||||
Qutex &firstFailedQutex);
|
||||
|
||||
// Disable copy constructor and assignment operator
|
||||
QutexAcquisitionHistoryTracker(
|
||||
@@ -123,6 +136,15 @@ private:
|
||||
~QutexAcquisitionHistoryTracker() = default;
|
||||
|
||||
private:
|
||||
/** EXPLANATION:
|
||||
* We use a SpinLock here instead of a Qutex because this acquisition
|
||||
* history tracker is invoked within the LockerAndInvoker.
|
||||
* Since LockerAndInvoker is too tightly coupled with Qutex workings, using
|
||||
* a Qutex here would create a circular dependency or deadlock situation.
|
||||
* Therefore, it's best to use a SpinLock on the history class to avoid
|
||||
* these coupling issues.
|
||||
*/
|
||||
SpinLock acquisitionHistoryLock;
|
||||
AcquisitionHistoryMap acquisitionHistory;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user