From b8a2f0495e6ecd4ac379e91fb88531bbeeceb46d Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Wed, 16 Apr 2003 20:55:41 +0000 Subject: [PATCH] evaluation version of deadlock detect mutex --- src/libCom/osi/epicsMutex.cpp | 52 +++++++++++++++++++++++++++++++++++ src/libCom/osi/epicsMutex.h | 21 ++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/libCom/osi/epicsMutex.cpp b/src/libCom/osi/epicsMutex.cpp index 4ee460580..94c7cfb62 100644 --- a/src/libCom/osi/epicsMutex.cpp +++ b/src/libCom/osi/epicsMutex.cpp @@ -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; +} + diff --git a/src/libCom/osi/epicsMutex.h b/src/libCom/osi/epicsMutex.h index 883c5bcd7..1bce729d3 100644 --- a/src/libCom/osi/epicsMutex.h +++ b/src/libCom/osi/epicsMutex.h @@ -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