43 # ifdef LOG_LAST_OWNER 59 const char * what ()
const throw ();
62 const char * epicsMutex::mutexCreateFailed::what ()
const throw ()
64 return "epicsMutex::mutexCreateFailed()";
70 const char * what ()
const throw ();
73 const char * epicsMutex::invalidMutex::what ()
const throw ()
75 return "epicsMutex::invalidMutex()";
78 static void epicsMutexOsiInit(
void *) {
82 epicsMutexGlobalLock = epicsMutexOsdCreate();
92 id = epicsMutexOsdCreate();
109 # ifdef LOG_LAST_OWNER 110 pmutexNode->lastOwner = 0;
133 epicsMutexOsdDestroy(pmutexNode->
id);
150 # ifdef LOG_LAST_OWNER 162 epicsMutexOsdTryLock(pmutexNode->
id);
163 # ifdef LOG_LAST_OWNER 194 # ifdef LOG_LAST_OWNER 195 char threadName [255];
196 if ( pmutexNode->lastOwner ) {
197 # error currently not safe to fetch name for stale thread 199 threadName, sizeof ( threadName ) );
202 strcpy ( threadName,
"<not used>" );
204 printf(
"epicsMutexId %p last owner \"%s\" source %s line %d\n",
205 (
void *)pmutexNode, threadName,
208 printf(
"epicsMutexId %p source %s line %d\n",
209 (
void *)pmutexNode, pmutexNode->
pFileName,
213 epicsMutexOsdShow(pmutexNode->
id,level-1);
224 printf(
"ellCount(&mutexList) %d ellCount(&freeList) %d\n",
233 status = epicsMutexOsdTryLock(pmutexNode->
id);
249 #if !defined(__GNUC__) || __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<8) 250 epicsMutex :: epicsMutex () :
253 if ( this->
id == 0 ) {
254 throw mutexCreateFailed ();
262 if ( this->
id == 0 ) {
263 throw mutexCreateFailed ();
267 epicsMutex ::~epicsMutex ()
276 throw invalidMutex ();
280 bool epicsMutex::tryLock ()
287 throw invalidMutex ();
292 void epicsMutex::unlock ()
297 void epicsMutex :: show (
unsigned level )
const 302 static epicsThreadPrivate < epicsDeadlockDetectMutex >
303 * pCurrentMutexLevel = 0;
310 pCurrentMutexLevel =
new epicsThreadPrivate < epicsDeadlockDetectMutex > ();
313 epicsDeadlockDetectMutex::
314 epicsDeadlockDetectMutex ( hierarchyLevel_t level ) :
315 hierarchyLevel ( level ), pPreviousLevel ( 0 )
321 epicsDeadlockDetectMutex::~epicsDeadlockDetectMutex ()
325 void epicsDeadlockDetectMutex::show (
unsigned level )
const 327 this->
mutex.show ( level );
332 epicsDeadlockDetectMutex * pPrev = pCurrentMutexLevel->get();
333 if ( pPrev && pPrev !=
this ) {
334 if ( pPrev->hierarchyLevel >= this->hierarchyLevel ) {
335 errlogPrintf (
"!!!! Deadlock Vulnerability Detected !!!! " 336 "at level %u and moving to level %u\n",
337 pPrev->hierarchyLevel,
338 this->hierarchyLevel );
342 if ( pPrev && pPrev !=
this ) {
343 pCurrentMutexLevel->set (
this );
344 this->pPreviousLevel = pPrev;
348 void epicsDeadlockDetectMutex::unlock ()
350 pCurrentMutexLevel->set ( this->pPreviousLevel );
351 this->
mutex.unlock ();
354 bool epicsDeadlockDetectMutex::tryLock ()
356 bool success = this->
mutex.tryLock ();
358 this->pPreviousLevel = pCurrentMutexLevel->get();
359 pCurrentMutexLevel->set (
this );
#define assert(exp)
Declare that a condition should be true.
#define ellCount(PLIST)
Report the number of nodes in a list.
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
Destroy an epicsMutex semaphore.
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
epicsMutexId epicsStdCall epicsMutexOsiMustCreate(const char *pFileName, int lineno)
Internal API, used by epicsMutexMustCreate().
void epicsDeadlockDetectMutexInitFunc(void *)
#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)
A doubly-linked list library.
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
#define ellNext(PNODE)
Find the next node in list.
#define EPICS_THREAD_ONCE_INIT
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
LIBCOM_API void epicsStdCall epicsThreadGetName(epicsThreadId id, char *name, size_t size)
#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)
void epicsMutexCleanup(void)
int errlogPrintf(const char *pFormat,...)
epicsMutexLockStatus epicsStdCall epicsMutexLock(epicsMutexId pmutexNode)
Claim the semaphore, waiting until it's free if currently owned owned by a different thread...
epicsMutexLockStatus epicsStdCall epicsMutexTryLock(epicsMutexId pmutexNode)
Similar to epicsMutexLock() except that the call returns immediately, with the return status indicati...
#define ellInit(PLIST)
Initialize a list type.
#define epicsMutexCreate()
Create an epicsMutex semaphore for use from C code.
void epicsStdCall epicsMutexShow(epicsMutexId pmutexNode, unsigned int level)
Display information about the semaphore.
#define epicsMutexOsdUnlock(ID)
#define epicsMutexOsdLock(ID)
#define VALGRIND_MEMPOOL_FREE(pool, addr)
epicsMutexId epicsStdCall epicsMutexOsiCreate(const char *pFileName, int lineno)
Internal API, used by epicsMutexCreate().
C++ and C descriptions for a thread.
void epicsStdCall epicsMutexShowAll(int onlyLocked, unsigned int level)
Display information about all epicsMutex semaphores.
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
#define ellFirst(PLIST)
Find the first node in list.
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)