29 #define checkStatus(status,message) \ 31 errlogPrintf("epicsMutex %s failed: error %s\n", \ 32 (message), strerror((status))); \ 34 #define checkStatusQuit(status,message,method) \ 36 errlogPrintf("epicsMutex %s failed: error %s\n", \ 37 (message), strerror((status))); \ 38 cantProceed((method)); \ 41 static int mutexLock(pthread_mutex_t *
id)
45 while ((status = pthread_mutex_lock(
id)) == EINTR) {
46 errlogPrintf(
"pthread_mutex_lock returned EINTR. Violates SUSv3\n");
53 #undef _POSIX_THREAD_PROCESS_SHARED 54 #undef _POSIX_THREAD_PRIO_INHERIT 64 #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 74 pmutex = calloc(1,
sizeof(*pmutex));
78 status = pthread_mutexattr_init(&pmutex->
mutexAttr);
82 #if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 83 status = pthread_mutexattr_setprotocol(&pmutex->
mutexAttr,
84 PTHREAD_PRIO_INHERIT);
88 status = pthread_mutexattr_settype(&pmutex->
mutexAttr,
89 PTHREAD_MUTEX_RECURSIVE);
94 status = pthread_mutex_init(&pmutex->
lock, &pmutex->
mutexAttr);
100 pthread_mutexattr_destroy(&pmutex->
mutexAttr);
110 status = pthread_mutex_destroy(&pmutex->
lock);
112 status = pthread_mutexattr_destroy(&pmutex->
mutexAttr);
121 status = pthread_mutex_unlock(&pmutex->
lock);
122 checkStatus(status,
"pthread_mutex_unlock epicsMutexOsdUnlock");
129 status = mutexLock(&pmutex->
lock);
132 errlogMessage(
"epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n");
143 status = pthread_mutex_trylock(&pmutex->
lock);
147 errlogMessage(
"epicsMutex pthread_mutex_trylock failed: error epicsMutexOsdTryLock");
158 printf(
" pthread_mutex_t* uaddr=%p\n", &pmutex->
lock);
167 #if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 168 pthread_condattr_t condAttr;
179 pmutex = calloc(1,
sizeof(*pmutex));
183 status = pthread_mutexattr_init(&pmutex->
mutexAttr);
187 #if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 188 status = pthread_mutexattr_setprotocol(
189 &pmutex->
mutexAttr,PTHREAD_PRIO_INHERIT);
193 status = pthread_mutex_init(&pmutex->
lock, &pmutex->
mutexAttr);
197 #if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 198 status = pthread_condattr_init(&pmutex->condAttr);
200 status = pthread_condattr_setpshared(&pmutex->condAttr,
201 PTHREAD_PROCESS_PRIVATE);
202 checkStatus(status,
"pthread_condattr_setpshared");
203 status = pthread_cond_init(&pmutex->
waitToBeOwner, &pmutex->condAttr);
213 pthread_mutex_destroy(&pmutex->
lock);
215 pthread_mutexattr_destroy(&pmutex->
mutexAttr);
227 #if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 228 status = pthread_condattr_destroy(&pmutex->condAttr);
230 status = pthread_mutex_destroy(&pmutex->
lock);
232 status = pthread_mutexattr_destroy(&pmutex->
mutexAttr);
241 status = mutexLock(&pmutex->
lock);
242 checkStatus(status,
"pthread_mutex_lock epicsMutexOsdUnlock");
246 if ((pmutex->
count <= 0) || (pmutex->
ownerTid != pthread_self())) {
247 pthread_mutex_unlock(&pmutex->
lock);
248 checkStatus(status,
"pthread_mutex_unlock epicsMutexOsdUnlock");
249 errlogPrintf(
"epicsMutexOsdUnlock but caller is not owner\n");
250 cantProceed(
"epicsMutexOsdUnlock but caller is not owner");
255 if (pmutex->
count == 0) {
259 checkStatusQuit(status,
"pthread_cond_signal epicsMutexOsdUnlock",
"epicsMutexOsdUnlock");
262 status = pthread_mutex_unlock(&pmutex->
lock);
263 checkStatus(status,
"pthread_mutex_unlock epicsMutexOsdUnlock");
266 static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
270 while ((status = pthread_cond_wait(condId, mutexId)) == EINTR) {
271 errlogPrintf(
"pthread_cond_wait returned EINTR. Violates SUSv3\n");
278 pthread_t tid = pthread_self();
282 status = mutexLock(&pmutex->
lock);
284 checkStatus(status,
"pthread_mutex_lock epicsMutexOsdLock");
288 while (pmutex->
owned && !pthread_equal(pmutex->
ownerTid, tid))
294 status = pthread_mutex_unlock(&pmutex->
lock);
295 checkStatus(status,
"pthread_mutex_unlock epicsMutexOsdLock");
303 pthread_t tid = pthread_self();
307 status = mutexLock(&pmutex->
lock);
309 checkStatus(status,
"pthread_mutex_lock epicsMutexOsdTryLock");
313 if (!pmutex->
owned || pthread_equal(pmutex->
ownerTid, tid)) {
322 status = pthread_mutex_unlock(&pmutex->
lock);
323 checkStatus(status,
"pthread_mutex_unlock epicsMutexOsdTryLock");
331 printf(
"ownerTid %p count %d owned %d\n",
An EPICS-specific replacement for ANSI C's assert.
void epicsMutexOsdUnlock(struct epicsMutexOSD *pmutex)
#define checkStatus(status, message)
struct epicsMutexOSD epicsMutexOSD
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *pmutex)
#define checkStatusQuit(status, message, method)
epicsMutexOSD * epicsMutexOsdCreate(void)
APIs for the epicsMutex mutual exclusion semaphore.
pthread_mutexattr_t mutexAttr
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *pmutex)
int errlogPrintf(const char *pFormat,...)
int errlogMessage(const char *message)
LIBCOM_API void cantProceed(const char *msg,...)
Routines for code that can't continue or return after an error.
void epicsMutexOsdDestroy(struct epicsMutexOSD *pmutex)
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
pthread_cond_t waitToBeOwner
void epicsMutexOsdShow(struct epicsMutexOSD *pmutex, unsigned int level)