evaluation version of deadlock detect mutex
This commit is contained in:
@@ -235,4 +235,56 @@ void epicsMutex :: show ( unsigned level ) const
|
||||
epicsMutexShow ( this->id, level );
|
||||
}
|
||||
|
||||
static epicsThreadPrivate < epicsDeadlockDetectMutex >
|
||||
currentMutexLevel;
|
||||
|
||||
epicsDeadlockDetectMutex::
|
||||
epicsDeadlockDetectMutex ( hierarchyLevel_t level ) :
|
||||
hierarchyLevel ( level ), pPreviousLevel ( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
epicsDeadlockDetectMutex::~epicsDeadlockDetectMutex ()
|
||||
{
|
||||
}
|
||||
|
||||
void epicsDeadlockDetectMutex::show ( unsigned level ) const
|
||||
{
|
||||
this->mutex.show ( level );
|
||||
}
|
||||
|
||||
void epicsDeadlockDetectMutex::lock ()
|
||||
{
|
||||
epicsDeadlockDetectMutex * pPrev = currentMutexLevel.get();
|
||||
if ( pPrev && pPrev != this ) {
|
||||
if ( pPrev->hierarchyLevel >= this->hierarchyLevel ) {
|
||||
errlogPrintf ( "!!!! Deadlock Vulnerability Detected !!!! "
|
||||
"at level %u and moving to level %u\n",
|
||||
pPrev->hierarchyLevel,
|
||||
this->hierarchyLevel );
|
||||
}
|
||||
}
|
||||
this->mutex.lock ();
|
||||
if ( pPrev && pPrev != this ) {
|
||||
currentMutexLevel.set ( this );
|
||||
this->pPreviousLevel = pPrev;
|
||||
}
|
||||
}
|
||||
|
||||
void epicsDeadlockDetectMutex::unlock ()
|
||||
{
|
||||
currentMutexLevel.set ( this->pPreviousLevel );
|
||||
this->mutex.unlock ();
|
||||
}
|
||||
|
||||
bool epicsDeadlockDetectMutex::tryLock ()
|
||||
{
|
||||
bool success = this->mutex.tryLock ();
|
||||
if ( success ) {
|
||||
this->pPreviousLevel = currentMutexLevel.get();
|
||||
currentMutexLevel.set ( this );
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ typedef enum {
|
||||
|
||||
class epicsShareClass epicsMutex {
|
||||
public:
|
||||
class mutexCreateFailed {}; // exception
|
||||
class invalidMutex {}; // exception
|
||||
class mutexCreateFailed {}; /* exception */
|
||||
class invalidMutex {}; /* exception */
|
||||
epicsMutex ();
|
||||
~epicsMutex ();
|
||||
void show ( unsigned level ) const;
|
||||
@@ -39,6 +39,23 @@ private:
|
||||
epicsMutex & operator = ( const epicsMutex & );
|
||||
};
|
||||
|
||||
class epicsShareClass epicsDeadlockDetectMutex {
|
||||
public:
|
||||
typedef unsigned hierarchyLevel_t;
|
||||
epicsDeadlockDetectMutex ( unsigned hierarchyLevel_t );
|
||||
~epicsDeadlockDetectMutex ();
|
||||
void show ( unsigned level ) const;
|
||||
void lock (); /* blocks until success */
|
||||
void unlock ();
|
||||
bool tryLock (); /* true if successful */
|
||||
private:
|
||||
epicsMutex mutex;
|
||||
const hierarchyLevel_t hierarchyLevel;
|
||||
class epicsDeadlockDetectMutex * pPreviousLevel;
|
||||
epicsDeadlockDetectMutex ( const epicsDeadlockDetectMutex & );
|
||||
epicsDeadlockDetectMutex & operator = ( const epicsDeadlockDetectMutex & );
|
||||
};
|
||||
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user