This is Unofficial EPICS BASE Doxygen Site
epicsMutex.cpp File Reference
#include <new>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "epicsStdio.h"
#include "epicsThread.h"
#include "valgrind/valgrind.h"
#include "ellLib.h"
#include "errlog.h"
#include "epicsMutex.h"
+ Include dependency graph for epicsMutex.cpp:

Go to the source code of this file.

Classes

struct  epicsMutexParm
 
class  epicsMutex::mutexCreateFailed
 
class  epicsMutex::invalidMutex
 

Functions

epicsMutexId epicsStdCall epicsMutexOsiCreate (const char *pFileName, int lineno)
 Internal API, used by epicsMutexCreate(). More...
 
epicsMutexId epicsStdCall epicsMutexOsiMustCreate (const char *pFileName, int lineno)
 Internal API, used by epicsMutexMustCreate(). More...
 
void epicsStdCall epicsMutexDestroy (epicsMutexId pmutexNode)
 Destroy an epicsMutex semaphore. More...
 
void epicsStdCall epicsMutexUnlock (epicsMutexId pmutexNode)
 Release the semaphore. More...
 
epicsMutexLockStatus epicsStdCall epicsMutexLock (epicsMutexId pmutexNode)
 Claim the semaphore, waiting until it's free if currently owned owned by a different thread. More...
 
epicsMutexLockStatus epicsStdCall epicsMutexTryLock (epicsMutexId pmutexNode)
 Similar to epicsMutexLock() except that the call returns immediately, with the return status indicating if the semaphore is currently owned by this thread or another thread. More...
 
void epicsMutexCleanup (void)
 
void epicsStdCall epicsMutexShow (epicsMutexId pmutexNode, unsigned int level)
 Display information about the semaphore. More...
 
void epicsStdCall epicsMutexShowAll (int onlyLocked, unsigned int level)
 Display information about all epicsMutex semaphores. More...
 
void epicsDeadlockDetectMutexInitFunc (void *)
 

Function Documentation

void epicsDeadlockDetectMutexInitFunc ( void *  )

Definition at line 308 of file epicsMutex.cpp.

309 {
310  pCurrentMutexLevel = new epicsThreadPrivate < epicsDeadlockDetectMutex > ();
311 }
void epicsMutexCleanup ( void  )

Definition at line 176 of file epicsMutex.cpp.

177 {
178  ELLNODE *cur;
179  epicsMutexLockStatus lockStat =
180  epicsMutexOsdLock(epicsMutexGlobalLock);
181  assert ( lockStat == epicsMutexLockOK );
182 
183  while((cur=ellGet(&freeList))!=NULL) {
184  VALGRIND_MEMPOOL_FREE(&freeList, cur);
185  free(cur);
186  }
187 
188  epicsMutexOsdUnlock(epicsMutexGlobalLock);
189 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
Definition: ellLib.c:147
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
epicsMutexLockStatus
Definition: epicsMutex.h:51
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22
#define epicsMutexOsdLock(ID)
Definition: osdMutex.h:24
#define VALGRIND_MEMPOOL_FREE(pool, addr)
Definition: valgrind.h:6485
void epicsStdCall epicsMutexDestroy ( epicsMutexId  id)

Destroy an epicsMutex semaphore.

Parameters
idThe mutex identifier.

Definition at line 127 of file epicsMutex.cpp.

128 {
129  epicsMutexLockStatus lockStat =
130  epicsMutexOsdLock(epicsMutexGlobalLock);
131  assert ( lockStat == epicsMutexLockOK );
132  ellDelete(&mutexList,&pmutexNode->node);
133  epicsMutexOsdDestroy(pmutexNode->id);
134  VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
135  VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node));
136  ellAdd(&freeList,&pmutexNode->node);
137  epicsMutexOsdUnlock(epicsMutexGlobalLock);
138 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)
Definition: valgrind.h:6480
epicsMutexLockStatus
Definition: epicsMutex.h:51
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22
#define epicsMutexOsdLock(ID)
Definition: osdMutex.h:24
#define VALGRIND_MEMPOOL_FREE(pool, addr)
Definition: valgrind.h:6485
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
epicsMutexLockStatus epicsStdCall epicsMutexLock ( epicsMutexId  id)

Claim the semaphore, waiting until it's free if currently owned owned by a different thread.

This call blocks until the calling thread can get exclusive access to the semaphore.

Note
After a successful lock(), additional recursive locks may be issued by the same thread, but each must have an associated unlock().
Parameters
idThe mutex identifier.
Returns
Status indicator.

Definition at line 145 of file epicsMutex.cpp.

147 {
149  epicsMutexOsdLock(pmutexNode->id);
150 # ifdef LOG_LAST_OWNER
151  if ( status == epicsMutexLockOK ) {
152  pmutexNode->lastOwner = epicsThreadGetIdSelf();
153  }
154 # endif
155  return status;
156 }
pvd::Status status
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
epicsMutexLockStatus
Definition: epicsMutex.h:51
#define epicsMutexOsdLock(ID)
Definition: osdMutex.h:24
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
epicsMutexId epicsStdCall epicsMutexOsiCreate ( const char *  pFileName,
int  lineno 
)

Internal API, used by epicsMutexCreate().

Definition at line 85 of file epicsMutex.cpp.

87 {
88  epicsMutexOSD * id;
89 
90  epicsThreadOnce(&epicsMutexOsiOnce, epicsMutexOsiInit, NULL);
91 
92  id = epicsMutexOsdCreate();
93  if(!id) {
94  return 0;
95  }
96  epicsMutexLockStatus lockStat =
97  epicsMutexOsdLock(epicsMutexGlobalLock);
98  assert ( lockStat == epicsMutexLockOK );
99  epicsMutexParm *pmutexNode =
100  reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) );
101  if(pmutexNode) {
102  ellDelete(&freeList,&pmutexNode->node);
103  VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode);
104  } else {
105  pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) );
106  }
107  VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm));
108  pmutexNode->id = id;
109 # ifdef LOG_LAST_OWNER
110  pmutexNode->lastOwner = 0;
111 # endif
112  pmutexNode->pFileName = pFileName;
113  pmutexNode->lineno = lineno;
114  ellAdd(&mutexList,&pmutexNode->node);
115  epicsMutexOsdUnlock(epicsMutexGlobalLock);
116  return(pmutexNode);
117 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
int lineno
Definition: antelope.c:33
#define NULL
Definition: catime.c:38
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)
Definition: valgrind.h:6480
epicsMutexLockStatus
Definition: epicsMutex.h:51
const char * pFileName
Definition: epicsMutex.cpp:46
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22
#define epicsMutexOsdLock(ID)
Definition: osdMutex.h:24
#define VALGRIND_MEMPOOL_FREE(pool, addr)
Definition: valgrind.h:6485
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
epicsMutexId epicsStdCall epicsMutexOsiMustCreate ( const char *  pFileName,
int  lineno 
)

Internal API, used by epicsMutexMustCreate().

Definition at line 119 of file epicsMutex.cpp.

121 {
122  epicsMutexId id = epicsMutexOsiCreate(pFileName,lineno);
123  assert(id);
124  return(id );
125 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
int lineno
Definition: antelope.c:33
epicsMutexId epicsStdCall epicsMutexOsiCreate(const char *pFileName, int lineno)
Internal API, used by epicsMutexCreate().
Definition: epicsMutex.cpp:85
void epicsStdCall epicsMutexShow ( epicsMutexId  id,
unsigned int  level 
)

Display information about the semaphore.

Note
Results are architecture dependant.
Parameters
idThe mutex identifier.
levelDesired information level to report

Definition at line 191 of file epicsMutex.cpp.

193 {
194 # ifdef LOG_LAST_OWNER
195  char threadName [255];
196  if ( pmutexNode->lastOwner ) {
197 # error currently not safe to fetch name for stale thread
198  epicsThreadGetName ( pmutexNode->lastOwner,
199  threadName, sizeof ( threadName ) );
200  }
201  else {
202  strcpy ( threadName, "<not used>" );
203  }
204  printf("epicsMutexId %p last owner \"%s\" source %s line %d\n",
205  (void *)pmutexNode, threadName,
206  pmutexNode->pFileName, pmutexNode->lineno);
207 # else
208  printf("epicsMutexId %p source %s line %d\n",
209  (void *)pmutexNode, pmutexNode->pFileName,
210  pmutexNode->lineno);
211 # endif
212  if ( level > 0 ) {
213  epicsMutexOsdShow(pmutexNode->id,level-1);
214  }
215 }
#define printf
Definition: epicsStdio.h:41
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
LIBCOM_API void epicsStdCall epicsThreadGetName(epicsThreadId id, char *name, size_t size)
Definition: osdThread.c:857
const char * pFileName
Definition: epicsMutex.cpp:46
void epicsStdCall epicsMutexShowAll ( int  onlyLocked,
unsigned int  level 
)

Display information about all epicsMutex semaphores.

Note
Results are architecture dependant.
Parameters
onlyLockedNon-zero to show only locked semaphores.
levelDesired information level to report

Definition at line 217 of file epicsMutex.cpp.

218 {
219  epicsMutexParm *pmutexNode;
220 
221  if (epicsMutexOsiOnce == EPICS_THREAD_ONCE_INIT)
222  return;
223 
224  printf("ellCount(&mutexList) %d ellCount(&freeList) %d\n",
225  ellCount(&mutexList),ellCount(&freeList));
226  epicsMutexLockStatus lockStat =
227  epicsMutexOsdLock(epicsMutexGlobalLock);
228  assert ( lockStat == epicsMutexLockOK );
229  pmutexNode = reinterpret_cast < epicsMutexParm * > ( ellFirst(&mutexList) );
230  while(pmutexNode) {
231  if(onlyLocked) {
233  status = epicsMutexOsdTryLock(pmutexNode->id);
234  if(status==epicsMutexLockOK) {
235  epicsMutexOsdUnlock(pmutexNode->id);
236  pmutexNode =
237  reinterpret_cast < epicsMutexParm * >
238  ( ellNext(&pmutexNode->node) );
239  continue;
240  }
241  }
242  epicsMutexShow(pmutexNode, level);
243  pmutexNode =
244  reinterpret_cast < epicsMutexParm * > ( ellNext(&pmutexNode->node) );
245  }
246  epicsMutexOsdUnlock(epicsMutexGlobalLock);
247 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
pvd::Status status
#define printf
Definition: epicsStdio.h:41
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
epicsMutexLockStatus
Definition: epicsMutex.h:51
void epicsStdCall epicsMutexShow(epicsMutexId pmutexNode, unsigned int level)
Display information about the semaphore.
Definition: epicsMutex.cpp:191
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22
#define epicsMutexOsdLock(ID)
Definition: osdMutex.h:24
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
epicsMutexLockStatus epicsStdCall epicsMutexTryLock ( epicsMutexId  id)

Similar to epicsMutexLock() except that the call returns immediately, with the return status indicating if the semaphore is currently owned by this thread or another thread.

Returns
epicsMutexLockOK if the resource is now owned by the caller.
epicsMutexLockTimeout if some other thread owns the resource.

Definition at line 158 of file epicsMutex.cpp.

160 {
162  epicsMutexOsdTryLock(pmutexNode->id);
163 # ifdef LOG_LAST_OWNER
164  if ( status == epicsMutexLockOK ) {
165  pmutexNode->lastOwner = epicsThreadGetIdSelf();
166  }
167 # endif
168  return status;
169 }
pvd::Status status
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
epicsMutexLockStatus
Definition: epicsMutex.h:51
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
void epicsStdCall epicsMutexUnlock ( epicsMutexId  id)

Release the semaphore.

Parameters
idThe mutex identifier.
Note
If a thread issues recursive locks, it must call epicsMutexUnlock() as many times as it calls epicsMutexLock() or equivalents.

Definition at line 140 of file epicsMutex.cpp.

141 {
142  epicsMutexOsdUnlock(pmutexNode->id);
143 }
epicsMutexOSD * id
Definition: epicsMutex.cpp:42
#define epicsMutexOsdUnlock(ID)
Definition: osdMutex.h:22