Merged Michael's dontcant branch.
This removes various calls to cantProceed() and its relatives and replaces them with an error return status when a resource allocation fails. It only does it for routines that already have an error status return, so it makes no API changes, and will prevent threads from being suspended unnecessarily.
This commit is contained in:
@@ -104,7 +104,11 @@ GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
|
||||
epicsMutexMustLock(pgphPvt->lock);
|
||||
plist = paplist[hash];
|
||||
if (plist == NULL) {
|
||||
plist = callocMustSucceed(1, sizeof(ELLLIST), "gphAdd");
|
||||
plist = calloc(1, sizeof(ELLLIST));
|
||||
if(!plist){
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return NULL;
|
||||
}
|
||||
ellInit(plist);
|
||||
paplist[hash] = plist;
|
||||
}
|
||||
@@ -119,10 +123,12 @@ GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
|
||||
pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode);
|
||||
}
|
||||
|
||||
pgphNode = callocMustSucceed(1, sizeof(GPHENTRY), "gphAdd");
|
||||
pgphNode->name = name;
|
||||
pgphNode->pvtid = pvtid;
|
||||
ellAdd(plist, (ELLNODE *)pgphNode);
|
||||
pgphNode = calloc(1, sizeof(GPHENTRY));
|
||||
if(pgphNode) {
|
||||
pgphNode->name = name;
|
||||
pgphNode->pvtid = pvtid;
|
||||
ellAdd(plist, (ELLNODE *)pgphNode);
|
||||
}
|
||||
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return (pgphNode);
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errlog.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "cantProceed.h"
|
||||
#include "epicsString.h"
|
||||
#include "macLib.h"
|
||||
|
||||
@@ -27,8 +28,10 @@ macEnvExpand(const char *str)
|
||||
char *dest = NULL;
|
||||
int n;
|
||||
|
||||
if (macCreateHandle(&handle, pairs))
|
||||
cantProceed("macEnvExpand: macCreateHandle failed.");
|
||||
if (macCreateHandle(&handle, pairs)){
|
||||
errlogMessage("macEnvExpand: macCreateHandle failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
destCapacity *= 2;
|
||||
@@ -37,7 +40,10 @@ macEnvExpand(const char *str)
|
||||
* keep the original contents.
|
||||
*/
|
||||
free(dest);
|
||||
dest = mallocMustSucceed(destCapacity, "macEnvExpand");
|
||||
dest = malloc(destCapacity);
|
||||
if(!dest)
|
||||
goto done;
|
||||
|
||||
n = macExpandString(handle, str, dest, destCapacity);
|
||||
} while (n >= (destCapacity - 1));
|
||||
|
||||
@@ -51,7 +57,8 @@ macEnvExpand(const char *str)
|
||||
dest = realloc(dest, n);
|
||||
}
|
||||
|
||||
done:
|
||||
if (macDeleteHandle(handle))
|
||||
cantProceed("macEnvExpand: macDeleteHandle failed.");
|
||||
errlogMessage("macEnvExpand: macDeleteHandle failed.");
|
||||
return dest;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <string.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
#include <cantProceed.h>
|
||||
#include "epicsMessageQueue.h"
|
||||
#include "errlog.h"
|
||||
|
||||
@@ -35,11 +34,14 @@ epicsShareFunc epicsMessageQueueId epicsShareAPI
|
||||
epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
epicsMessageQueueId id = (epicsMessageQueueId)callocMustSucceed(1, sizeof(*id), "epicsMessageQueueCreate");
|
||||
epicsMessageQueueId id = calloc(1, sizeof(*id));
|
||||
rtems_interrupt_level level;
|
||||
static char c1 = 'a';
|
||||
static char c2 = 'a';
|
||||
static char c3 = 'a';
|
||||
|
||||
if(!id)
|
||||
return NULL;
|
||||
|
||||
sc = rtems_message_queue_create (rtems_build_name ('Q', c3, c2, c1),
|
||||
capacity,
|
||||
@@ -47,6 +49,7 @@ epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
|
||||
RTEMS_FIFO|RTEMS_LOCAL,
|
||||
&id->id);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
free(id);
|
||||
errlogPrintf ("Can't create message queue: %s\n", rtems_status_text (sc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -74,24 +74,46 @@ epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate(
|
||||
epicsMessageQueueId pmsg;
|
||||
unsigned int slotBytes, slotLongs;
|
||||
|
||||
assert(capacity != 0);
|
||||
pmsg = (epicsMessageQueueId)callocMustSucceed(1, sizeof(*pmsg), "epicsMessageQueueCreate");
|
||||
if(capacity == 0)
|
||||
return NULL;
|
||||
|
||||
pmsg = (epicsMessageQueueId)calloc(1, sizeof(*pmsg));
|
||||
if(!pmsg)
|
||||
return NULL;
|
||||
|
||||
pmsg->capacity = capacity;
|
||||
pmsg->maxMessageSize = maxMessageSize;
|
||||
slotLongs = 1 + ((maxMessageSize + sizeof(unsigned long) - 1) / sizeof(unsigned long));
|
||||
slotBytes = slotLongs * sizeof(unsigned long);
|
||||
pmsg->buf = (unsigned long *)callocMustSucceed(pmsg->capacity, slotBytes, "epicsMessageQueueCreate");
|
||||
|
||||
pmsg->mutex = epicsMutexCreate();
|
||||
pmsg->buf = (unsigned long*)calloc(pmsg->capacity, slotBytes);
|
||||
if(!pmsg->buf || !pmsg->mutex) {
|
||||
if(pmsg->mutex)
|
||||
epicsMutexDestroy(pmsg->mutex);
|
||||
free(pmsg->buf);
|
||||
free(pmsg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pmsg->inPtr = pmsg->outPtr = pmsg->firstMessageSlot = (char *)&pmsg->buf[0];
|
||||
pmsg->lastMessageSlot = (char *)&pmsg->buf[(capacity - 1) * slotLongs];
|
||||
pmsg->full = false;
|
||||
pmsg->slotSize = slotBytes;
|
||||
pmsg->mutex = epicsMutexMustCreate();
|
||||
|
||||
ellInit(&pmsg->sendQueue);
|
||||
ellInit(&pmsg->receiveQueue);
|
||||
ellInit(&pmsg->eventFreeList);
|
||||
return pmsg;
|
||||
}
|
||||
|
||||
static void
|
||||
freeEventNode(struct eventNode *enode)
|
||||
{
|
||||
epicsEventDestroy(enode->event);
|
||||
free(enode);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI
|
||||
epicsMessageQueueDestroy(epicsMessageQueueId pmsg)
|
||||
{
|
||||
@@ -99,8 +121,7 @@ epicsMessageQueueDestroy(epicsMessageQueueId pmsg)
|
||||
|
||||
while ((evp = reinterpret_cast < struct eventNode * >
|
||||
( ellGet(&pmsg->eventFreeList) ) ) != NULL) {
|
||||
epicsEventDestroy(evp->event);
|
||||
free(evp);
|
||||
freeEventNode(evp);
|
||||
}
|
||||
epicsMutexDestroy(pmsg->mutex);
|
||||
free(pmsg->buf);
|
||||
@@ -114,9 +135,15 @@ getEventNode(epicsMessageQueueId pmsg)
|
||||
|
||||
evp = reinterpret_cast < struct eventNode * > ( ellGet(&pmsg->eventFreeList) );
|
||||
if (evp == NULL) {
|
||||
evp = (struct eventNode *) callocMustSucceed(1, sizeof(*evp),
|
||||
"epicsMessageQueueGetEventNode");
|
||||
evp->event = epicsEventMustCreate(epicsEventEmpty);
|
||||
epicsEventId eid = epicsEventCreate(epicsEventEmpty);
|
||||
evp = (struct eventNode *) calloc(1, sizeof(*evp));
|
||||
if(!evp || !eid) {
|
||||
free(evp);
|
||||
if(eid)
|
||||
epicsEventDestroy(eid);
|
||||
return NULL;
|
||||
}
|
||||
evp->event = eid;
|
||||
}
|
||||
return evp;
|
||||
}
|
||||
@@ -133,7 +160,9 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, bool wait, bo
|
||||
/*
|
||||
* See if message can be sent
|
||||
*/
|
||||
epicsMutexLock(pmsg->mutex);
|
||||
if(epicsMutexLock(pmsg->mutex)!=epicsMutexLockOK)
|
||||
return -1;
|
||||
|
||||
if ((pmsg->numberOfSendersWaiting > 0)
|
||||
|| (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL))) {
|
||||
/*
|
||||
@@ -150,18 +179,32 @@ mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, bool wait, bo
|
||||
struct threadNode threadNode;
|
||||
threadNode.evp = getEventNode(pmsg);
|
||||
threadNode.eventSent = false;
|
||||
if (!threadNode.evp) {
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ellAdd(&pmsg->sendQueue, &threadNode.link);
|
||||
pmsg->numberOfSendersWaiting++;
|
||||
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
|
||||
if(haveTimeout)
|
||||
epicsEventWaitWithTimeout(threadNode.evp->event, timeout);
|
||||
else
|
||||
epicsEventWait(threadNode.evp->event);
|
||||
epicsMutexLock(pmsg->mutex);
|
||||
|
||||
if(epicsMutexLock(pmsg->mutex)!=epicsMutexLockOK){
|
||||
freeEventNode(threadNode.evp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!threadNode.eventSent)
|
||||
ellDelete(&pmsg->sendQueue, &threadNode.link);
|
||||
pmsg->numberOfSendersWaiting--;
|
||||
|
||||
ellAdd(&pmsg->eventFreeList, &threadNode.evp->link);
|
||||
|
||||
if (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) {
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
return -1;
|
||||
@@ -227,7 +270,9 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, bool wait,
|
||||
/*
|
||||
* If there's a message on the queue, copy it
|
||||
*/
|
||||
epicsMutexLock(pmsg->mutex);
|
||||
if(epicsMutexLock(pmsg->mutex)!=epicsMutexLockOK)
|
||||
return -1;
|
||||
|
||||
myOutPtr = (char *)pmsg->outPtr;
|
||||
if ((myOutPtr != pmsg->inPtr) || pmsg->full) {
|
||||
int ret;
|
||||
@@ -282,17 +327,31 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, bool wait,
|
||||
threadNode.buf = message;
|
||||
threadNode.size = size;
|
||||
threadNode.eventSent = false;
|
||||
|
||||
if(!threadNode.evp) {
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ellAdd(&pmsg->receiveQueue, &threadNode.link);
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
|
||||
if(haveTimeout)
|
||||
epicsEventWaitWithTimeout(threadNode.evp->event, timeout);
|
||||
else
|
||||
epicsEventWait(threadNode.evp->event);
|
||||
epicsMutexLock(pmsg->mutex);
|
||||
|
||||
if(epicsMutexLock(pmsg->mutex)!=epicsMutexLockOK){
|
||||
freeEventNode(threadNode.evp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!threadNode.eventSent)
|
||||
ellDelete(&pmsg->receiveQueue, &threadNode.link);
|
||||
ellAdd(&pmsg->eventFreeList, &threadNode.evp->link);
|
||||
|
||||
epicsMutexUnlock(pmsg->mutex);
|
||||
|
||||
if(threadNode.eventSent && (threadNode.size <= size))
|
||||
return threadNode.size;
|
||||
return -1;
|
||||
@@ -322,7 +381,7 @@ epicsMessageQueuePending(epicsMessageQueueId pmsg)
|
||||
char *myInPtr, *myOutPtr;
|
||||
int nmsg;
|
||||
|
||||
epicsMutexLock(pmsg->mutex);
|
||||
epicsMutexMustLock(pmsg->mutex);
|
||||
myInPtr = (char *)pmsg->inPtr;
|
||||
myOutPtr = (char *)pmsg->outPtr;
|
||||
if (pmsg->full)
|
||||
|
||||
@@ -31,12 +31,6 @@
|
||||
if((status)) { \
|
||||
errlogPrintf("epicsMutex %s failed: error %s\n",(message),strerror((status)));}
|
||||
|
||||
#define checkStatusQuit(status,message,method) \
|
||||
if(status) { \
|
||||
errlogPrintf("epicsMutex %s failed: error %s\n",(message),strerror((status))); \
|
||||
cantProceed((method)); \
|
||||
}
|
||||
|
||||
static int mutexLock(pthread_mutex_t *id)
|
||||
{
|
||||
int status;
|
||||
@@ -70,9 +64,13 @@ epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
epicsMutexOSD *pmutex;
|
||||
int status;
|
||||
|
||||
pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
|
||||
pmutex = calloc(1, sizeof(*pmutex));
|
||||
if(!pmutex)
|
||||
goto fail;
|
||||
|
||||
status = pthread_mutexattr_init(&pmutex->mutexAttr);
|
||||
checkStatusQuit(status,"pthread_mutexattr_init", "epicsMutexOsdCreate");
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
#if defined _POSIX_THREAD_PRIO_INHERIT
|
||||
status = pthread_mutexattr_setprotocol(&pmutex->mutexAttr,
|
||||
@@ -82,11 +80,20 @@ epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
|
||||
status = pthread_mutexattr_settype(&pmutex->mutexAttr,
|
||||
PTHREAD_MUTEX_RECURSIVE);
|
||||
if (errVerbose) checkStatus(status, "pthread_mutexattr_settype");
|
||||
checkStatus(status, "pthread_mutexattr_settype");
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
|
||||
checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
|
||||
if (status)
|
||||
goto dattr;
|
||||
return pmutex;
|
||||
|
||||
dattr:
|
||||
pthread_mutexattr_destroy(&pmutex->mutexAttr);
|
||||
fail:
|
||||
free(pmutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
|
||||
@@ -105,17 +112,19 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock");
|
||||
}
|
||||
|
||||
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!pmutex) return epicsMutexLockError;
|
||||
status = mutexLock(&pmutex->lock);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");
|
||||
if(status) {
|
||||
errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n");
|
||||
return epicsMutexLockError;
|
||||
}
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
@@ -127,7 +136,10 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
|
||||
status = pthread_mutex_trylock(&pmutex->lock);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
if (status == EBUSY) return epicsMutexLockTimeout;
|
||||
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");
|
||||
if(status) {
|
||||
errlogMessage("epicsMutex pthread_mutex_trylock failed: error epicsMutexOsdTryLock");
|
||||
return epicsMutexLockError;
|
||||
}
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
@@ -153,9 +165,13 @@ epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
epicsMutexOSD *pmutex;
|
||||
int status;
|
||||
|
||||
pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
|
||||
pmutex = calloc(1, sizeof(*pmutex));
|
||||
if(!pmutex)
|
||||
return NULL;
|
||||
|
||||
status = pthread_mutexattr_init(&pmutex->mutexAttr);
|
||||
checkStatusQuit(status, "pthread_mutexattr_init", "epicsMutexOsdCreate");
|
||||
if(status)
|
||||
goto fail;
|
||||
|
||||
#if defined _POSIX_THREAD_PRIO_INHERIT
|
||||
status = pthread_mutexattr_setprotocol(
|
||||
@@ -164,7 +180,8 @@ epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
#endif /*_POSIX_THREAD_PRIO_INHERIT*/
|
||||
|
||||
status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
|
||||
checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
|
||||
if(status)
|
||||
goto dattr;
|
||||
|
||||
#if defined _POSIX_THREAD_PROCESS_SHARED
|
||||
status = pthread_condattr_init(&pmutex->condAttr);
|
||||
@@ -176,8 +193,18 @@ epicsMutexOSD * epicsMutexOsdCreate(void) {
|
||||
#else
|
||||
status = pthread_cond_init(&pmutex->waitToBeOwner, 0);
|
||||
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
|
||||
checkStatusQuit(status, "pthread_cond_init", "epicsMutexOsdCreate");
|
||||
if(status)
|
||||
goto dmutex;
|
||||
|
||||
return pmutex;
|
||||
|
||||
dmutex:
|
||||
pthread_mutex_destroy(&pmutex->lock);
|
||||
dattr:
|
||||
pthread_mutexattr_destroy(&pmutex->mutexAttr);
|
||||
fail:
|
||||
free(pmutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex)
|
||||
@@ -201,12 +228,15 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
|
||||
int status;
|
||||
|
||||
status = mutexLock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdUnlock");
|
||||
checkStatus(status, "pthread_mutex_lock epicsMutexOsdUnlock");
|
||||
if(status)
|
||||
return;
|
||||
|
||||
if ((pmutex->count <= 0) || (pmutex->ownerTid != pthread_self())) {
|
||||
pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock");
|
||||
errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n");
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
|
||||
cantProceed("epicsMutexOsdUnlock but caller is not owner");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -214,11 +244,12 @@ void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
|
||||
if (pmutex->count == 0) {
|
||||
pmutex->owned = 0;
|
||||
pmutex->ownerTid = 0;
|
||||
pthread_cond_signal(&pmutex->waitToBeOwner);
|
||||
status = pthread_cond_signal(&pmutex->waitToBeOwner);
|
||||
checkStatus(status, "pthread_cond_signal epicsMutexOsdUnlock");
|
||||
}
|
||||
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock");
|
||||
}
|
||||
|
||||
static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId)
|
||||
@@ -239,7 +270,9 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
|
||||
if (!pmutex || !tid) return epicsMutexLockError;
|
||||
status = mutexLock(&pmutex->lock);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");
|
||||
checkStatus(status, "pthread_mutex_lock epicsMutexOsdLock");
|
||||
if(status)
|
||||
return epicsMutexLockError;
|
||||
|
||||
while (pmutex->owned && !pthread_equal(pmutex->ownerTid, tid))
|
||||
condWait(&pmutex->waitToBeOwner, &pmutex->lock);
|
||||
@@ -248,7 +281,9 @@ epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
|
||||
pmutex->count++;
|
||||
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdLock");
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdLock");
|
||||
if(status)
|
||||
return epicsMutexLockError;
|
||||
return epicsMutexLockOK;
|
||||
}
|
||||
|
||||
@@ -260,7 +295,9 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
|
||||
|
||||
status = mutexLock(&pmutex->lock);
|
||||
if (status == EINVAL) return epicsMutexLockError;
|
||||
checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");
|
||||
checkStatus(status, "pthread_mutex_lock epicsMutexOsdTryLock");
|
||||
if(status)
|
||||
return epicsMutexLockError;
|
||||
|
||||
if (!pmutex->owned || pthread_equal(pmutex->ownerTid, tid)) {
|
||||
pmutex->ownerTid = tid;
|
||||
@@ -272,7 +309,9 @@ epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
|
||||
}
|
||||
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdTryLock");
|
||||
checkStatus(status, "pthread_mutex_unlock epicsMutexOsdTryLock");
|
||||
if(status)
|
||||
return epicsMutexLockError;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,9 +158,16 @@ static epicsThreadOSD * create_threadInfo(const char *name)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo;
|
||||
|
||||
pthreadInfo = callocMustSucceed(1,sizeof(*pthreadInfo),"create_threadInfo");
|
||||
pthreadInfo->suspendEvent = epicsEventMustCreate(epicsEventEmpty);
|
||||
pthreadInfo->name = epicsStrDup(name);
|
||||
pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name)+1);
|
||||
if(!pthreadInfo)
|
||||
return NULL;
|
||||
pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty);
|
||||
if(!pthreadInfo->suspendEvent){
|
||||
free(pthreadInfo);
|
||||
return NULL;
|
||||
}
|
||||
pthreadInfo->name = (char*)&pthreadInfo[1];
|
||||
strcpy(pthreadInfo->name, name);
|
||||
return pthreadInfo;
|
||||
}
|
||||
|
||||
@@ -172,6 +179,8 @@ static epicsThreadOSD * init_threadInfo(const char *name,
|
||||
int status;
|
||||
|
||||
pthreadInfo = create_threadInfo(name);
|
||||
if(!pthreadInfo)
|
||||
return NULL;
|
||||
pthreadInfo->createFunc = funptr;
|
||||
pthreadInfo->createArg = parm;
|
||||
status = pthread_attr_init(&pthreadInfo->attr);
|
||||
@@ -197,14 +206,17 @@ static void free_threadInfo(epicsThreadOSD *pthreadInfo)
|
||||
int status;
|
||||
|
||||
status = mutexLock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo");
|
||||
checkStatus(status,"pthread_mutex_lock free_threadInfo");
|
||||
if(status)
|
||||
return;
|
||||
if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node);
|
||||
status = pthread_mutex_unlock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo");
|
||||
checkStatus(status,"pthread_mutex_unlock free_threadInfo");
|
||||
epicsEventDestroy(pthreadInfo->suspendEvent);
|
||||
status = pthread_attr_destroy(&pthreadInfo->attr);
|
||||
checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo");
|
||||
free(pthreadInfo->name);
|
||||
checkStatus(status,"pthread_attr_destroy free_threadInfo");
|
||||
if(status)
|
||||
return;
|
||||
free(pthreadInfo);
|
||||
}
|
||||
|
||||
@@ -349,6 +361,7 @@ static void once(void)
|
||||
if(errVerbose) fprintf(stderr,"task priorities are not implemented\n");
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0);
|
||||
assert(pthreadInfo!=NULL);
|
||||
status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
|
||||
checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit");
|
||||
status = mutexLock(&listLock);
|
||||
@@ -526,6 +539,8 @@ static epicsThreadOSD *createImplicit(void)
|
||||
tid = pthread_self();
|
||||
sprintf(name, "non-EPICS_%ld", (long)tid);
|
||||
pthreadInfo = create_threadInfo(name);
|
||||
if(!pthreadInfo)
|
||||
return NULL;
|
||||
pthreadInfo->tid = tid;
|
||||
pthreadInfo->osiPriority = 0;
|
||||
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
|
||||
@@ -539,7 +554,11 @@ static epicsThreadOSD *createImplicit(void)
|
||||
}
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
|
||||
checkStatusQuit(status,"pthread_setspecific","createImplicit");
|
||||
checkStatus(status,"pthread_setspecific createImplicit");
|
||||
if(status){
|
||||
free_threadInfo(pthreadInfo);
|
||||
return NULL;
|
||||
}
|
||||
/* pthread_cleanup_push(nonEPICSthreadCleanup, pthreadInfo); */
|
||||
return pthreadInfo;
|
||||
}
|
||||
@@ -553,7 +572,7 @@ epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void)
|
||||
if(pthreadInfo==NULL)
|
||||
pthreadInfo = createImplicit();
|
||||
pthreadInfo->isSuspended = 1;
|
||||
epicsEventMustWait(pthreadInfo->suspendEvent);
|
||||
epicsEventWait(pthreadInfo->suspendEvent);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo)
|
||||
@@ -703,14 +722,16 @@ epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name) {
|
||||
|
||||
assert(epicsThreadOnceCalled);
|
||||
status = mutexLock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsThreadGetId");
|
||||
checkStatus(status,"pthread_mutex_lock epicsThreadGetId");
|
||||
if(status)
|
||||
return NULL;
|
||||
pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
if(strcmp(name,pthreadInfo->name) == 0) break;
|
||||
pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
status = pthread_mutex_unlock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadGetId");
|
||||
checkStatus(status,"pthread_mutex_unlock epicsThreadGetId");
|
||||
|
||||
return(pthreadInfo);
|
||||
}
|
||||
@@ -764,14 +785,16 @@ epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level)
|
||||
epicsThreadInit();
|
||||
epicsThreadShow(0,level);
|
||||
status = mutexLock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll");
|
||||
checkStatus(status,"pthread_mutex_lock epicsThreadShowAll");
|
||||
if(status)
|
||||
return;
|
||||
pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
showThreadInfo(pthreadInfo,level);
|
||||
pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
status = pthread_mutex_unlock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll");
|
||||
checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll");
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsigned int level)
|
||||
@@ -786,7 +809,9 @@ epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsi
|
||||
return;
|
||||
}
|
||||
status = mutexLock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll");
|
||||
checkStatus(status,"pthread_mutex_lock epicsThreadShowAll");
|
||||
if(status)
|
||||
return;
|
||||
pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
if (((epicsThreadId)pthreadInfo == showThread)
|
||||
@@ -797,7 +822,7 @@ epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsi
|
||||
pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
status = pthread_mutex_unlock(&listLock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll");
|
||||
checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll");
|
||||
if (!found)
|
||||
printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);
|
||||
}
|
||||
@@ -809,9 +834,13 @@ epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void)
|
||||
int status;
|
||||
|
||||
epicsThreadInit();
|
||||
key = callocMustSucceed(1,sizeof(pthread_key_t),"epicsThreadPrivateCreate");
|
||||
key = calloc(1,sizeof(pthread_key_t));
|
||||
if(!key)
|
||||
return NULL;
|
||||
status = pthread_key_create(key,0);
|
||||
checkStatusQuit(status,"pthread_key_create","epicsThreadPrivateCreate");
|
||||
checkStatus(status,"pthread_key_create epicsThreadPrivateCreate");
|
||||
if(status)
|
||||
return NULL;
|
||||
return((epicsThreadPrivateId)key);
|
||||
}
|
||||
|
||||
@@ -850,6 +879,8 @@ epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum ()
|
||||
{
|
||||
double hz;
|
||||
hz = sysconf ( _SC_CLK_TCK );
|
||||
if(hz<0)
|
||||
return 0.0;
|
||||
return 1.0 / hz;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbDefs.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsRingBytes.h"
|
||||
|
||||
/*
|
||||
@@ -39,9 +38,11 @@ typedef struct ringPvt {
|
||||
|
||||
epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size)
|
||||
{
|
||||
ringPvt *pring = mallocMustSucceed(sizeof(ringPvt),"epicsRingBytesCreate");
|
||||
ringPvt *pring = malloc(sizeof(ringPvt) + size + SLOP);
|
||||
if(!pring)
|
||||
return NULL;
|
||||
pring->size = size + SLOP;
|
||||
pring->buffer = mallocMustSucceed(pring->size,"ringCreate");
|
||||
pring->buffer = (char*)&pring[1];
|
||||
pring->nextGet = 0;
|
||||
pring->nextPut = 0;
|
||||
return((void *)pring);
|
||||
@@ -50,7 +51,6 @@ epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size)
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
free((void *)pring->buffer);
|
||||
free((void *)pring);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user