replace osiSem by epicsMutex/epiceEvent
This commit is contained in:
@@ -122,10 +122,6 @@ INC += osdSock.h
|
||||
INC += osiInterrupt.h
|
||||
INC += osdInterrupt.h
|
||||
|
||||
#Marty remove the following
|
||||
INC += osiSem.h
|
||||
INC += osdSem.h
|
||||
|
||||
|
||||
INC += epicsMutex.h
|
||||
INC += osdMutex.h
|
||||
@@ -154,9 +150,6 @@ SRCS += osdFindSymbol.c
|
||||
SRCS += osdInterrupt.c
|
||||
SRCS += osdPoolStatus.c
|
||||
|
||||
#Marty remove the following
|
||||
SRCS += osdSem.c
|
||||
|
||||
SRCS += osdMutex.c
|
||||
SRCS += osdEvent.c
|
||||
SRCS += osdThread.c
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "ellLib.h"
|
||||
#include "dbmf.h"
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct itemHeader{
|
||||
|
||||
typedef struct dbmfPrivate {
|
||||
ELLLIST chunkList;
|
||||
semMutexId sem;
|
||||
epicsMutexId lock;
|
||||
size_t size;
|
||||
size_t allocSize;
|
||||
int chunkItems;
|
||||
@@ -55,7 +55,7 @@ int epicsShareAPI dbmfInit(size_t size, int chunkItems)
|
||||
}
|
||||
pdbmfPvt = &dbmfPvt;
|
||||
ellInit(&pdbmfPvt->chunkList);
|
||||
pdbmfPvt->sem = semMutexMustCreate();
|
||||
pdbmfPvt->lock = epicsMutexMustCreate();
|
||||
/*allign to at least a double*/
|
||||
pdbmfPvt->size = size + size%sizeof(double);
|
||||
pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader);
|
||||
@@ -78,7 +78,7 @@ void* epicsShareAPI dbmfMalloc(size_t size)
|
||||
itemHeader *pitemHeader;
|
||||
|
||||
if(!pdbmfPvt) dbmfInit(DBMF_SIZE,DBMF_INITIAL_ITEMS);
|
||||
semMutexMustTake(pdbmfPvt->sem);
|
||||
epicsMutexMustLock(pdbmfPvt->lock);
|
||||
pfreeList = &pdbmfPvt->freeList;
|
||||
if(*pfreeList == NULL) {
|
||||
int i;
|
||||
@@ -88,7 +88,7 @@ void* epicsShareAPI dbmfMalloc(size_t size)
|
||||
nbytesTotal = pdbmfPvt->chunkSize + sizeof(chunkNode);
|
||||
pmem = (char *)malloc(nbytesTotal);
|
||||
if(!pmem) {
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
printf("dbmfMalloc malloc failed\n");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ void* epicsShareAPI dbmfMalloc(size_t size)
|
||||
pitemHeader->pchunkNode = NULL;
|
||||
if(dbmfDebug) printf("dbmfMalloc: size %d mem %p\n",size,pmem);
|
||||
}
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
return((void *)(pmem + sizeof(itemHeader)));
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ void epicsShareAPI dbmfFree(void* mem)
|
||||
return;
|
||||
}
|
||||
pmem -= sizeof(itemHeader);
|
||||
semMutexMustTake(pdbmfPvt->sem);
|
||||
epicsMutexMustLock(pdbmfPvt->lock);
|
||||
pitemHeader = (itemHeader *)pmem;
|
||||
if(!pitemHeader->pchunkNode) {
|
||||
if(dbmfDebug) printf("dbmfGree: mem %p\n",pmem);
|
||||
@@ -149,7 +149,7 @@ void epicsShareAPI dbmfFree(void* mem)
|
||||
*pnextFree = *pfreeList; *pfreeList = pnextFree;
|
||||
pdbmfPvt->nAlloc--; pdbmfPvt->nFree++;
|
||||
}
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
}
|
||||
|
||||
int epicsShareAPI dbmfShow(int level)
|
||||
@@ -176,13 +176,13 @@ int epicsShareAPI dbmfShow(int level)
|
||||
if(level>1) {
|
||||
void **pnextFree;;
|
||||
|
||||
semMutexMustTake(pdbmfPvt->sem);
|
||||
epicsMutexMustLock(pdbmfPvt->lock);
|
||||
pnextFree = (void**)pdbmfPvt->freeList;
|
||||
while(pnextFree) {
|
||||
printf("%p\n",*pnextFree);
|
||||
pnextFree = (void**)*pnextFree;
|
||||
}
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -196,11 +196,11 @@ void epicsShareAPI dbmfFreeChunks(void)
|
||||
printf("dbmfFreeChunks called but dbmfInit never called\n");
|
||||
return;
|
||||
}
|
||||
semMutexMustTake(pdbmfPvt->sem);
|
||||
epicsMutexMustLock(pdbmfPvt->lock);
|
||||
if(pdbmfPvt->nFree
|
||||
!= (pdbmfPvt->chunkItems * ellCount(&pdbmfPvt->chunkList))) {
|
||||
printf("dbmfFinish: not all free\n");
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
return;
|
||||
}
|
||||
pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList);
|
||||
@@ -211,5 +211,5 @@ void epicsShareAPI dbmfFreeChunks(void)
|
||||
pchunkNode = pnext;
|
||||
}
|
||||
pdbmfPvt->nFree = 0; pdbmfPvt->freeList = NULL;
|
||||
semMutexGive(pdbmfPvt->sem);
|
||||
epicsMutexUnlock(pdbmfPvt->lock);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ of this distribution.
|
||||
#define ERRLOG_INIT
|
||||
#include "dbDefs.h"
|
||||
#include "osiThread.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "osiInterrupt.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "errMdef.h"
|
||||
@@ -70,18 +71,18 @@ typedef struct msgNode {
|
||||
} msgNode;
|
||||
|
||||
LOCAL struct {
|
||||
semBinaryId errlogTaskWaitForWork;
|
||||
semMutexId msgQueueLock;
|
||||
semMutexId listenerLock;
|
||||
ELLLIST listenerList;
|
||||
ELLLIST msgQueue;
|
||||
msgNode *pnextSend;
|
||||
int errlogInitFailed;
|
||||
int buffersize;
|
||||
int sevToLog;
|
||||
int toConsole;
|
||||
int missedMessages;
|
||||
void *pbuffer;
|
||||
epicsEventId errlogTaskWaitForWork;
|
||||
epicsMutexId msgQueueLock;
|
||||
epicsMutexId listenerLock;
|
||||
ELLLIST listenerList;
|
||||
ELLLIST msgQueue;
|
||||
msgNode *pnextSend;
|
||||
int errlogInitFailed;
|
||||
int buffersize;
|
||||
int sevToLog;
|
||||
int toConsole;
|
||||
int missedMessages;
|
||||
void *pbuffer;
|
||||
}pvtData;
|
||||
|
||||
epicsShareFunc int epicsShareAPIV errlogPrintf( const char *pFormat, ...)
|
||||
@@ -212,11 +213,11 @@ epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
|
||||
errlogInit(0);
|
||||
plistenerNode = pvtCalloc(1,sizeof(listenerNode));
|
||||
semMutexMustTake(pvtData.listenerLock);
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
plistenerNode->listener = listener;
|
||||
plistenerNode->pPrivate = pPrivate;
|
||||
ellAdd(&pvtData.listenerList,&plistenerNode->node);
|
||||
semMutexGive(pvtData.listenerLock);
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
@@ -225,7 +226,7 @@ epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
semMutexMustTake(pvtData.listenerLock);
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
if(plistenerNode->listener==listener) {
|
||||
@@ -235,7 +236,7 @@ epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
}
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semMutexGive(pvtData.listenerLock);
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
if(!plistenerNode) printf("errlogRemoveListener did not find listener\n");
|
||||
}
|
||||
|
||||
@@ -308,9 +309,9 @@ static void errlogInitPvt(void *arg)
|
||||
ellInit(&pvtData.listenerList);
|
||||
ellInit(&pvtData.msgQueue);
|
||||
pvtData.toConsole = TRUE;
|
||||
pvtData.errlogTaskWaitForWork = semBinaryMustCreate(semEmpty);
|
||||
pvtData.listenerLock = semMutexMustCreate();
|
||||
pvtData.msgQueueLock = semMutexMustCreate();
|
||||
pvtData.errlogTaskWaitForWork = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.listenerLock = epicsMutexMustCreate();
|
||||
pvtData.msgQueueLock = epicsMutexMustCreate();
|
||||
/*Allow an extra MAX_MESSAGE_SIZE for extra margain of safety*/
|
||||
pbuffer = pvtCalloc(pvtData.buffersize+MAX_MESSAGE_SIZE,sizeof(char));
|
||||
pvtData.pbuffer = pbuffer;
|
||||
@@ -339,16 +340,16 @@ LOCAL void errlogTask(void)
|
||||
while(TRUE) {
|
||||
char *pmessage;
|
||||
|
||||
semBinaryMustTake(pvtData.errlogTaskWaitForWork);
|
||||
epicsEventMustWait(pvtData.errlogTaskWaitForWork);
|
||||
while((pmessage = msgbufGetSend())) {
|
||||
semMutexMustTake(pvtData.listenerLock);
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
if(pvtData.toConsole) printf("%s",pmessage);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
(*plistenerNode->listener)(plistenerNode->pPrivate, pmessage);
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semMutexGive(pvtData.listenerLock);
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
msgbufFreeSend();
|
||||
}
|
||||
}
|
||||
@@ -390,7 +391,7 @@ LOCAL char *msgbufGetFree()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
semMutexMustTake(pvtData.msgQueueLock);
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
if((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) {
|
||||
int nchar;
|
||||
|
||||
@@ -404,7 +405,7 @@ LOCAL char *msgbufGetFree()
|
||||
pvtData.pnextSend = pnextSend = msgbufGetNode();
|
||||
if(pnextSend) return(pnextSend->message);
|
||||
++pvtData.missedMessages;
|
||||
semMutexGive(pvtData.msgQueueLock);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -436,8 +437,8 @@ LOCAL void msgbufSetSize(int size)
|
||||
pnextSend->length = size+1;
|
||||
}
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
semMutexGive(pvtData.msgQueueLock);
|
||||
semBinaryGive(pvtData.errlogTaskWaitForWork);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
epicsEventSignal(pvtData.errlogTaskWaitForWork);
|
||||
}
|
||||
|
||||
/*errlogTask is the only task that calls msgbufGetSend and msgbufFreeSend*/
|
||||
@@ -448,9 +449,9 @@ LOCAL char * msgbufGetSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
semMutexMustTake(pvtData.msgQueueLock);
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
semMutexGive(pvtData.msgQueueLock);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
if(!pnextSend) return(0);
|
||||
return(pnextSend->message);
|
||||
}
|
||||
@@ -459,14 +460,14 @@ LOCAL void msgbufFreeSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
semMutexMustTake(pvtData.msgQueueLock);
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
if(!pnextSend) {
|
||||
printf("errlog: msgbufFreeSend logic error\n");
|
||||
threadSuspendSelf();
|
||||
}
|
||||
ellDelete(&pvtData.msgQueue,&pnextSend->node);
|
||||
semMutexGive(pvtData.msgQueueLock);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
}
|
||||
|
||||
LOCAL void *pvtCalloc(size_t count,size_t size)
|
||||
|
||||
@@ -59,7 +59,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "cantProceed.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "freeList.h"
|
||||
#include "adjustment.h"
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct {
|
||||
void *head;
|
||||
allocMem *mallochead;
|
||||
size_t nBlocksAvailable;
|
||||
semMutexId lock;
|
||||
epicsMutexId lock;
|
||||
}FREELISTPVT;
|
||||
|
||||
epicsShareFunc void epicsShareAPI
|
||||
@@ -87,7 +87,7 @@ epicsShareFunc void epicsShareAPI
|
||||
pfl->head = NULL;
|
||||
pfl->mallochead = NULL;
|
||||
pfl->nBlocksAvailable = 0u;
|
||||
pfl->lock = semMutexMustCreate();
|
||||
pfl->lock = epicsMutexMustCreate();
|
||||
*ppvt = (void *)pfl;
|
||||
return;
|
||||
}
|
||||
@@ -110,17 +110,17 @@ epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt)
|
||||
allocMem *pallocmem;
|
||||
int i;
|
||||
|
||||
semMutexMustTake(pfl->lock);
|
||||
epicsMutexMustLock(pfl->lock);
|
||||
ptemp = pfl->head;
|
||||
if(ptemp==0) {
|
||||
ptemp = (void *)malloc(pfl->nmalloc*pfl->size);
|
||||
if(ptemp==0) {
|
||||
semMutexGive(pfl->lock);
|
||||
epicsMutexUnlock(pfl->lock);
|
||||
return(0);
|
||||
}
|
||||
pallocmem = (allocMem *)calloc(1,sizeof(allocMem));
|
||||
if(pallocmem==0) {
|
||||
semMutexGive(pfl->lock);
|
||||
epicsMutexUnlock(pfl->lock);
|
||||
free(ptemp);
|
||||
return(0);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt)
|
||||
ppnext = pfl->head;
|
||||
pfl->head = *ppnext;
|
||||
pfl->nBlocksAvailable--;
|
||||
semMutexGive(pfl->lock);
|
||||
epicsMutexUnlock(pfl->lock);
|
||||
return(ptemp);
|
||||
}
|
||||
|
||||
@@ -149,12 +149,12 @@ epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem)
|
||||
FREELISTPVT *pfl = pvt;
|
||||
void **ppnext;
|
||||
|
||||
semMutexMustTake(pfl->lock);
|
||||
epicsMutexMustLock(pfl->lock);
|
||||
ppnext = pmem;
|
||||
*ppnext = pfl->head;
|
||||
pfl->head = pmem;
|
||||
pfl->nBlocksAvailable++;
|
||||
semMutexGive(pfl->lock);
|
||||
epicsMutexUnlock(pfl->lock);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt)
|
||||
@@ -170,7 +170,7 @@ epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt)
|
||||
free(phead);
|
||||
phead = pnext;
|
||||
}
|
||||
semMutexDestroy(pfl->lock);
|
||||
epicsMutexDestroy(pfl->lock);
|
||||
free(pvt);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "cantProceed.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "dbDefs.h"
|
||||
#include "ellLib.h"
|
||||
#include "epicsPrint.h"
|
||||
@@ -68,7 +68,7 @@ typedef struct gphPvt {
|
||||
int tableSize;
|
||||
int nShift;
|
||||
ELLLIST **paplist; /*pointer to array of pointers to ELLLIST */
|
||||
semMutexId lock;
|
||||
epicsMutexId lock;
|
||||
}gphPvt;
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void epicsShareAPI gphInitPvt(void **ppvt,int size)
|
||||
pgphPvt->tableSize = tableSize;
|
||||
pgphPvt->nShift = nShift;
|
||||
pgphPvt->paplist = myCalloc(tableSize, sizeof(ELLLIST *));
|
||||
pgphPvt->lock = semMutexMustCreate();
|
||||
pgphPvt->lock = epicsMutexMustCreate();
|
||||
*ppvt = (void *)pgphPvt;
|
||||
return;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ GPHENTRY * epicsShareAPI gphFind(void *pvt,const char *name,void *pvtid)
|
||||
if(pgphPvt==NULL) return(NULL);
|
||||
paplist = pgphPvt->paplist;
|
||||
hashInd = hash(name,pgphPvt->nShift);
|
||||
semMutexMustTake(pgphPvt->lock);
|
||||
epicsMutexMustLock(pgphPvt->lock);
|
||||
if ((gphlist=paplist[hashInd]) == NULL) {
|
||||
pgphNode = NULL;
|
||||
} else {
|
||||
@@ -174,7 +174,7 @@ GPHENTRY * epicsShareAPI gphFind(void *pvt,const char *name,void *pvtid)
|
||||
}
|
||||
pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
|
||||
}
|
||||
semMutexGive(pgphPvt->lock);
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return(pgphNode);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ GPHENTRY * epicsShareAPI gphAdd(void *pvt,const char *name,void *pvtid)
|
||||
if(pgphPvt==NULL) return(NULL);
|
||||
paplist = pgphPvt->paplist;
|
||||
hashInd = hash(name,pgphPvt->nShift);
|
||||
semMutexMustTake(pgphPvt->lock);
|
||||
epicsMutexMustLock(pgphPvt->lock);
|
||||
if(paplist[hashInd] == NULL) {
|
||||
paplist[hashInd] = myCalloc(1, sizeof(ELLLIST));
|
||||
ellInit(paplist[hashInd]);
|
||||
@@ -199,7 +199,7 @@ GPHENTRY * epicsShareAPI gphAdd(void *pvt,const char *name,void *pvtid)
|
||||
while(pgphNode) {
|
||||
if((strcmp(name,(char *)pgphNode->name) == 0)
|
||||
&&(pvtid == pgphNode->pvtid)) {
|
||||
semMutexGive(pgphPvt->lock);
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return(NULL);
|
||||
}
|
||||
pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
|
||||
@@ -208,7 +208,7 @@ GPHENTRY * epicsShareAPI gphAdd(void *pvt,const char *name,void *pvtid)
|
||||
pgphNode->name = name;
|
||||
pgphNode->pvtid = pvtid;
|
||||
ellAdd(plist, (ELLNODE*)pgphNode);
|
||||
semMutexGive(pgphPvt->lock);
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return (pgphNode);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ void epicsShareAPI gphDelete(void *pvt,const char *name,void *pvtid)
|
||||
if(pgphPvt==NULL) return;
|
||||
paplist = pgphPvt->paplist;
|
||||
hashInd = hash(name,pgphPvt->nShift);
|
||||
semMutexMustTake(pgphPvt->lock);
|
||||
epicsMutexMustLock(pgphPvt->lock);
|
||||
if(paplist[hashInd] == NULL) {
|
||||
pgphNode = NULL;
|
||||
} else {
|
||||
@@ -239,7 +239,7 @@ void epicsShareAPI gphDelete(void *pvt,const char *name,void *pvtid)
|
||||
}
|
||||
pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode);
|
||||
}
|
||||
semMutexGive(pgphPvt->lock);
|
||||
epicsMutexUnlock(pgphPvt->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
* RTEMS osdSem.c
|
||||
* $Id$
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
* (306) 966-6055
|
||||
*/
|
||||
|
||||
/*
|
||||
* We want to print out some information which is
|
||||
* normally hidden from application programs.
|
||||
*/
|
||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
|
||||
#include "osiSem.h"
|
||||
#include "osiThread.h"
|
||||
#include "errlog.h"
|
||||
|
||||
#define RTEMS_FAST_MUTEX
|
||||
/* #define EPICS_RTEMS_SEMAPHORE_STATS */
|
||||
/*
|
||||
* Some performance tuning instrumentation
|
||||
*/
|
||||
#ifdef EPICS_RTEMS_SEMAPHORE_STATS
|
||||
unsigned long semStat[6];
|
||||
#define SEMSTAT(i) semStat[i]++;
|
||||
#else
|
||||
#define SEMSTAT(i)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a simple binary semaphore
|
||||
*/
|
||||
semBinaryId
|
||||
semBinaryCreate(semInitialState initialState)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id sid;
|
||||
rtems_interrupt_level level;
|
||||
static char c1 = 'a';
|
||||
static char c2 = 'a';
|
||||
static char c3 = 'a';
|
||||
|
||||
sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1),
|
||||
initialState,
|
||||
RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
|
||||
0,
|
||||
&sid);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
errlogPrintf ("Can't create binary semaphore: %s\n", rtems_status_text (sc));
|
||||
return NULL;
|
||||
}
|
||||
rtems_interrupt_disable (level);
|
||||
if (c1 == 'z') {
|
||||
if (c2 == 'z') {
|
||||
if (c3 == 'z') {
|
||||
c3 = 'a';
|
||||
}
|
||||
else {
|
||||
c3++;
|
||||
}
|
||||
c2 = 'a';
|
||||
}
|
||||
else {
|
||||
c2++;
|
||||
}
|
||||
c1 = 'a';
|
||||
}
|
||||
else {
|
||||
c1++;
|
||||
}
|
||||
rtems_interrupt_enable (level);
|
||||
return (semBinaryId)sid;
|
||||
}
|
||||
|
||||
semBinaryId semBinaryMustCreate(semInitialState initialState)
|
||||
{
|
||||
semBinaryId id = semBinaryCreate (initialState);
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
semBinaryDestroy(semBinaryId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_semaphore_delete (sid);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
|
||||
}
|
||||
|
||||
void
|
||||
semBinaryGive(semBinaryId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_semaphore_release (sid);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc));
|
||||
}
|
||||
|
||||
semTakeStatus
|
||||
semBinaryTake(semBinaryId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
|
||||
SEMSTAT(0)
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
return semTakeError;
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
semTakeStatus
|
||||
semBinaryTakeTimeout(semBinaryId id, double timeOut)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
rtems_interval delay;
|
||||
extern double rtemsTicksPerSecond_double;
|
||||
|
||||
SEMSTAT(1)
|
||||
delay = timeOut * rtemsTicksPerSecond_double;
|
||||
if (delay == 0)
|
||||
delay = 1;
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return semTakeOK;
|
||||
else if (sc == RTEMS_TIMEOUT)
|
||||
return semTakeTimeout;
|
||||
else
|
||||
return semTakeError;
|
||||
}
|
||||
|
||||
semTakeStatus
|
||||
semBinaryTakeNoWait(semBinaryId id)
|
||||
{
|
||||
rtems_id sid = (rtems_id)id;
|
||||
rtems_status_code sc;
|
||||
|
||||
SEMSTAT(2)
|
||||
sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
return semTakeOK;
|
||||
else if (sc == RTEMS_UNSATISFIED)
|
||||
return semTakeTimeout;
|
||||
else
|
||||
return semTakeError;
|
||||
}
|
||||
|
||||
void
|
||||
semBinaryShow(semBinaryId id, unsigned int level)
|
||||
{
|
||||
#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
||||
rtems_id sid = (rtems_id)id;
|
||||
Semaphore_Control *the_semaphore;
|
||||
Semaphore_Control semaphore;
|
||||
Objects_Locations location;
|
||||
|
||||
the_semaphore = _Semaphore_Get (sid, &location);
|
||||
if (location != OBJECTS_LOCAL)
|
||||
return;
|
||||
/*
|
||||
* Yes, there's a race condition here since an interrupt might
|
||||
* change things while the copy is in progress, but the information
|
||||
* is only for display, so it's not that critical.
|
||||
*/
|
||||
semaphore = *the_semaphore;
|
||||
_Thread_Enable_dispatch();
|
||||
printf (" %8.8x ", sid);
|
||||
if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) {
|
||||
printf ("Count: %d", semaphore.Core_control.semaphore.count);
|
||||
}
|
||||
else {
|
||||
if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) {
|
||||
char name[20];
|
||||
threadGetName ((threadId)semaphore.Core_control.mutex.holder_id, name, sizeof name);
|
||||
printf ("Held by:%8.8x (%s) Nest count:%d",
|
||||
semaphore.Core_control.mutex.holder_id,
|
||||
name,
|
||||
semaphore.Core_control.mutex.nest_count);
|
||||
}
|
||||
else {
|
||||
printf ("Not Held");
|
||||
}
|
||||
}
|
||||
printf ("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
semMutexId
|
||||
semMutexCreate(void)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id sid;
|
||||
rtems_interrupt_level level;
|
||||
static char c1 = 'a';
|
||||
static char c2 = 'a';
|
||||
static char c3 = 'a';
|
||||
|
||||
sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1),
|
||||
1,
|
||||
RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
|
||||
0,
|
||||
&sid);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc));
|
||||
return NULL;
|
||||
}
|
||||
rtems_interrupt_disable (level);
|
||||
if (c1 == 'z') {
|
||||
if (c2 == 'z') {
|
||||
if (c3 == 'z') {
|
||||
c3 = 'a';
|
||||
}
|
||||
else {
|
||||
c3++;
|
||||
}
|
||||
c2 = 'a';
|
||||
}
|
||||
else {
|
||||
c2++;
|
||||
}
|
||||
c1 = 'a';
|
||||
}
|
||||
else {
|
||||
c1++;
|
||||
}
|
||||
rtems_interrupt_enable (level);
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
{
|
||||
Semaphore_Control *the_semaphore;
|
||||
Objects_Locations location;
|
||||
|
||||
the_semaphore = _Semaphore_Get( sid, &location );
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return the_semaphore;
|
||||
}
|
||||
#endif
|
||||
return (semMutexId)sid;
|
||||
}
|
||||
|
||||
semMutexId semMutexMustCreate(void)
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void semMutexDestroy(semMutexId id)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_id sid;
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
sid = the_semaphore->Object.id;
|
||||
#else
|
||||
sid = (rtems_id)id;
|
||||
#endif
|
||||
sc = rtems_semaphore_delete (sid);
|
||||
if (sc == RTEMS_RESOURCE_IN_USE) {
|
||||
rtems_semaphore_release (sid);
|
||||
sc = rtems_semaphore_delete (sid);
|
||||
}
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc));
|
||||
}
|
||||
|
||||
void semMutexGive(semMutexId id)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
_Thread_Disable_dispatch();
|
||||
_CORE_mutex_Surrender (
|
||||
&the_semaphore->Core_control.mutex,
|
||||
the_semaphore->Object.id,
|
||||
NULL
|
||||
);
|
||||
_Thread_Enable_dispatch();
|
||||
#else
|
||||
semBinaryGive (id);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTake(semMutexId id)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
ISR_Level level;
|
||||
SEMSTAT(3)
|
||||
_ISR_Disable( level );
|
||||
_CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
the_semaphore->Object.id,
|
||||
1, /* TRUE or FALSE */
|
||||
0, /* same as passed to obtain -- ticks */
|
||||
level
|
||||
);
|
||||
if (_Thread_Executing->Wait.return_code == 0)
|
||||
return semTakeOK;
|
||||
else
|
||||
return semTakeError;
|
||||
#else
|
||||
SEMSTAT(3)
|
||||
return semBinaryTake (id);
|
||||
#endif
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeTimeout(
|
||||
semMutexId id, double timeOut)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
ISR_Level level;
|
||||
rtems_interval delay;
|
||||
extern double rtemsTicksPerSecond_double;
|
||||
|
||||
SEMSTAT(4)
|
||||
delay = timeOut * rtemsTicksPerSecond_double;
|
||||
if (delay == 0)
|
||||
delay = 1;
|
||||
_ISR_Disable( level );
|
||||
_CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
the_semaphore->Object.id,
|
||||
1, /* TRUE or FALSE */
|
||||
delay, /* same as passed to obtain -- ticks */
|
||||
level
|
||||
);
|
||||
if (_Thread_Executing->Wait.return_code == 0)
|
||||
return semTakeOK;
|
||||
else
|
||||
return semTakeTimeout;
|
||||
#else
|
||||
SEMSTAT(4)
|
||||
return semBinaryTakeTimeout (id, timeOut);
|
||||
#endif
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeNoWait(semMutexId id)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
ISR_Level level;
|
||||
SEMSTAT(5)
|
||||
_ISR_Disable( level );
|
||||
_CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
the_semaphore->Object.id,
|
||||
0, /* TRUE or FALSE */
|
||||
0, /* same as passed to obtain -- ticks */
|
||||
level
|
||||
);
|
||||
if (_Thread_Executing->Wait.return_code == 0)
|
||||
return semTakeOK;
|
||||
else
|
||||
return semTakeTimeout;
|
||||
#else
|
||||
SEMSTAT(5)
|
||||
return semBinaryTakeNoWait (id);
|
||||
#endif
|
||||
}
|
||||
|
||||
epicsShareFunc void semMutexShow(semMutexId id,unsigned int level)
|
||||
{
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
Semaphore_Control *the_semaphore = (Semaphore_Control *)id;
|
||||
id = (semMutexId)the_semaphore->Object.id;
|
||||
#endif
|
||||
semBinaryShow (id,level);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
/*
|
||||
* RTEMS osdSem.h
|
||||
* $Id$
|
||||
* Author: W. Eric Norum
|
||||
* eric@cls.usask.ca
|
||||
* (306) 966-6055
|
||||
*/
|
||||
|
||||
/* osdSem.h not needed */
|
||||
@@ -1,571 +0,0 @@
|
||||
/* osiSem.c */
|
||||
/*
|
||||
* $Id$
|
||||
* WIN32 version
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
# define VC_EXTRALEAN
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
/* including less than this causes conflicts with winsock2.h :-( */
|
||||
#define _WIN32_WINNT 0x400
|
||||
#include <winsock2.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "shareLib.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "cantProceed.h"
|
||||
|
||||
static const unsigned mSecPerSecOsdSem = 1000u;
|
||||
|
||||
typedef struct binarySem {
|
||||
HANDLE handle;
|
||||
}binarySem;
|
||||
|
||||
|
||||
/*
|
||||
* semBinaryCreate ()
|
||||
*/
|
||||
epicsShareFunc semBinaryId epicsShareAPI semBinaryCreate ( semInitialState initialState )
|
||||
{
|
||||
binarySem *pSem;
|
||||
|
||||
pSem = malloc ( sizeof ( *pSem ) );
|
||||
if ( pSem ) {
|
||||
pSem->handle = CreateEvent ( NULL, FALSE, initialState?TRUE:FALSE, NULL );
|
||||
if ( pSem->handle == 0 ) {
|
||||
free ( pSem );
|
||||
pSem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ( semBinaryId ) pSem;
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryMustCreate ()
|
||||
*/
|
||||
epicsShareFunc semBinaryId epicsShareAPI semBinaryMustCreate ( semInitialState initialState )
|
||||
{
|
||||
semBinaryId id = semBinaryCreate ( initialState );
|
||||
assert ( id );
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryDestroy ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semBinaryDestroy (semBinaryId id)
|
||||
{
|
||||
binarySem *pSem = (binarySem *) id;
|
||||
|
||||
CloseHandle (pSem->handle);
|
||||
free (pSem);
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryGive ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semBinaryGive (semBinaryId id)
|
||||
{
|
||||
binarySem *pSem = (binarySem *) id;
|
||||
BOOL status;
|
||||
|
||||
status = SetEvent (pSem->handle);
|
||||
assert (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryTake ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTake (semBinaryId id)
|
||||
{
|
||||
binarySem *pSem = (binarySem *) id;
|
||||
DWORD status;
|
||||
|
||||
status = WaitForSingleObject (pSem->handle, INFINITE);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryTakeTimeout ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeTimeout (semBinaryId id, double timeOut)
|
||||
{
|
||||
binarySem *pSem = (binarySem *) id;
|
||||
DWORD status;
|
||||
DWORD tmo;
|
||||
|
||||
tmo = (DWORD) (timeOut * mSecPerSecOsdSem);
|
||||
status = WaitForSingleObject (pSem->handle, tmo);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else if (status == WAIT_TIMEOUT) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryTakeNoWait ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeNoWait (semBinaryId id)
|
||||
{
|
||||
binarySem *pSem = (binarySem *) id;
|
||||
DWORD status;
|
||||
|
||||
status = WaitForSingleObject (pSem->handle, 0);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else if (status == WAIT_TIMEOUT) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semBinaryShow ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semBinaryShow (semBinaryId id, unsigned level)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
typedef struct mutexSem {
|
||||
HANDLE handle;
|
||||
}mutexSem;
|
||||
|
||||
|
||||
/*
|
||||
* semMutexCreate ()
|
||||
*/
|
||||
epicsShareFunc semMutexId epicsShareAPI semMutexCreate (void)
|
||||
{
|
||||
mutexSem *pSem;
|
||||
|
||||
pSem = malloc ( sizeof (*pSem) );
|
||||
if (pSem) {
|
||||
pSem->handle = CreateMutex (NULL, FALSE, NULL);
|
||||
if (pSem->handle==0) {
|
||||
free (pSem);
|
||||
pSem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (semMutexId) pSem;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexMustCreate ()
|
||||
*/
|
||||
epicsShareFunc semBinaryId epicsShareAPI semMutexMustCreate ()
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexDestroy ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexDestroy (semMutexId id)
|
||||
{
|
||||
mutexSem *pSem = (mutexSem *) id;
|
||||
|
||||
CloseHandle (pSem->handle);
|
||||
free (pSem);
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexGive ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexGive (semMutexId id)
|
||||
{
|
||||
mutexSem *pSem = (mutexSem *) id;
|
||||
BOOL success;
|
||||
|
||||
success = ReleaseMutex (pSem->handle);
|
||||
assert (success);
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTake ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake (semMutexId id)
|
||||
{
|
||||
mutexSem *pSem = (mutexSem *) id;
|
||||
DWORD status;
|
||||
|
||||
status = WaitForSingleObject (pSem->handle, INFINITE);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeTimeout ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout (semMutexId id, double timeOut)
|
||||
{
|
||||
mutexSem *pSem = (mutexSem *) id;
|
||||
DWORD status;
|
||||
DWORD tmo;
|
||||
|
||||
tmo = (DWORD) (timeOut * mSecPerSecOsdSem);
|
||||
status = WaitForSingleObject (pSem->handle, tmo);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else if (status == WAIT_TIMEOUT) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeNoWait ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait (semMutexId id)
|
||||
{
|
||||
mutexSem *pSem = (mutexSem *) id;
|
||||
DWORD status;
|
||||
|
||||
status = WaitForSingleObject (pSem->handle, 0);
|
||||
if ( status == WAIT_OBJECT_0 ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else if (status == WAIT_TIMEOUT) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
else {
|
||||
return semTakeError;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexShow ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexShow (semMutexId id, unsigned level)
|
||||
{
|
||||
}
|
||||
|
||||
#elif 0
|
||||
|
||||
typedef struct mutexSem {
|
||||
CRITICAL_SECTION cs;
|
||||
} mutexSem;
|
||||
|
||||
/*
|
||||
* semMutexCreate ()
|
||||
*/
|
||||
epicsShareFunc semMutexId epicsShareAPI semMutexCreate ( void )
|
||||
{
|
||||
mutexSem *pSem;
|
||||
|
||||
pSem = malloc ( sizeof (*pSem) );
|
||||
if ( pSem ) {
|
||||
InitializeCriticalSection ( &pSem->cs );
|
||||
}
|
||||
|
||||
return (semMutexId) pSem;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexMustCreate ()
|
||||
*/
|
||||
epicsShareFunc semBinaryId epicsShareAPI semMutexMustCreate ()
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert ( id );
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexDestroy ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexDestroy ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
|
||||
DeleteCriticalSection ( &pSem->cs );
|
||||
free ( pSem );
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexGive ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexGive ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTake ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeTimeout ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout ( semMutexId id, double timeOut )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeNoWait ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
if ( TryEnterCriticalSection ( &pSem->cs ) ) {
|
||||
return semTakeOK;
|
||||
}
|
||||
else {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexShow ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexShow ( semMutexId id, unsigned level )
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef struct mutexSem {
|
||||
CRITICAL_SECTION cs;
|
||||
DWORD threadId;
|
||||
HANDLE unlockSignal;
|
||||
unsigned count;
|
||||
} mutexSem;
|
||||
|
||||
/*
|
||||
* semMutexCreate ()
|
||||
*/
|
||||
epicsShareFunc semMutexId epicsShareAPI semMutexCreate ( void )
|
||||
{
|
||||
mutexSem *pSem;
|
||||
|
||||
pSem = malloc ( sizeof (*pSem) );
|
||||
if ( pSem ) {
|
||||
pSem->unlockSignal = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
||||
if ( pSem->unlockSignal == 0 ) {
|
||||
free ( pSem );
|
||||
pSem = 0;
|
||||
}
|
||||
else {
|
||||
InitializeCriticalSection ( &pSem->cs );
|
||||
pSem->threadId = 0;
|
||||
pSem->count = 0u;
|
||||
}
|
||||
}
|
||||
return (semMutexId) pSem;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexMustCreate ()
|
||||
*/
|
||||
epicsShareFunc semBinaryId epicsShareAPI semMutexMustCreate ()
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert ( id );
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexDestroy ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexDestroy ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
|
||||
DeleteCriticalSection ( &pSem->cs );
|
||||
CloseHandle ( pSem->unlockSignal );
|
||||
free ( pSem );
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexGive ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexGive ( semMutexId id )
|
||||
{
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
unsigned signalNeeded;
|
||||
DWORD status;
|
||||
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
//assert ( pSem->threadId == GetCurrentThreadId () );
|
||||
assert ( pSem->count > 0u );
|
||||
pSem->count--;
|
||||
if ( pSem->count == 0 ) {
|
||||
pSem->threadId = 0;
|
||||
signalNeeded = 1;
|
||||
}
|
||||
else {
|
||||
signalNeeded = 0;
|
||||
}
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
|
||||
if ( signalNeeded ) {
|
||||
status = SetEvent ( pSem->unlockSignal );
|
||||
assert ( status );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTake ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake ( semMutexId id )
|
||||
{
|
||||
DWORD thisThread = GetCurrentThreadId ();
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
|
||||
while ( pSem->count && pSem->threadId != thisThread ) {
|
||||
DWORD status;
|
||||
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
status = WaitForSingleObject ( pSem->unlockSignal, INFINITE );
|
||||
if ( status == WAIT_TIMEOUT ) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
}
|
||||
|
||||
pSem->threadId = thisThread;
|
||||
assert ( pSem->count != UINT_MAX );
|
||||
pSem->count++;
|
||||
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeTimeout ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout ( semMutexId id, double timeOut )
|
||||
{
|
||||
DWORD thisThread = GetCurrentThreadId ();
|
||||
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
|
||||
while ( pSem->count && pSem->threadId != thisThread ) {
|
||||
DWORD tmo;
|
||||
DWORD status;
|
||||
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
tmo = ( DWORD ) ( timeOut * mSecPerSecOsdSem );
|
||||
status = WaitForSingleObject ( pSem->unlockSignal, tmo );
|
||||
if ( status == WAIT_TIMEOUT ) {
|
||||
return semTakeTimeout;
|
||||
}
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
}
|
||||
|
||||
pSem->threadId = thisThread;
|
||||
assert ( pSem->count != UINT_MAX );
|
||||
pSem->count++;
|
||||
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexTakeNoWait ()
|
||||
*/
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait ( semMutexId id )
|
||||
{
|
||||
DWORD thisThread = GetCurrentThreadId ();
|
||||
|
||||
mutexSem *pSem = ( mutexSem * ) id;
|
||||
|
||||
EnterCriticalSection ( &pSem->cs );
|
||||
|
||||
if ( pSem->count && pSem->threadId != thisThread ) {
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
return semTakeTimeout;
|
||||
}
|
||||
|
||||
pSem->threadId = thisThread;
|
||||
assert ( pSem->count != UINT_MAX );
|
||||
pSem->count++;
|
||||
|
||||
LeaveCriticalSection ( &pSem->cs );
|
||||
|
||||
return semTakeOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* semMutexShow ()
|
||||
*/
|
||||
epicsShareFunc void epicsShareAPI semMutexShow ( semMutexId id, unsigned level )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
/* osiSem.c */
|
||||
/*
|
||||
* $Id$
|
||||
* WIN32 version
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
* 505 665 1831
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*/
|
||||
|
||||
#ifndef osdSemh
|
||||
#define osdSemh
|
||||
|
||||
#endif /* osdSemh */
|
||||
@@ -17,28 +17,28 @@ of this distribution.
|
||||
#include <stdio.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "cantProceed.h"
|
||||
#include "errlog.h"
|
||||
#include "osiInterrupt.h"
|
||||
|
||||
static semMutexId globalLock=0;
|
||||
static epicsMutexId globalLock=0;
|
||||
static int firstTime = 1;
|
||||
|
||||
epicsShareFunc int epicsShareAPI interruptLock()
|
||||
{
|
||||
if(firstTime) {
|
||||
globalLock = semMutexMustCreate();
|
||||
globalLock = epicsMutexMustCreate();
|
||||
firstTime = 0;
|
||||
}
|
||||
semMutexMustTake(globalLock);
|
||||
epicsMutexMustLock(globalLock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI interruptUnlock(int key)
|
||||
{
|
||||
if(firstTime) cantProceed("interruptUnlock called before interruptLock\n");
|
||||
semMutexGive(globalLock);
|
||||
epicsMutexUnlock(globalLock);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI interruptIsInterruptContext() { return(0);}
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
/* osiSem.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 13AUG1999 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "osiSem.h"
|
||||
#include "osiThread.h"
|
||||
#include "cantProceed.h"
|
||||
#include "tsStamp.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAssert.h"
|
||||
|
||||
/* Until these can be demonstrated to work leave them undefined*/
|
||||
#undef _POSIX_THREAD_PROCESS_SHARED
|
||||
#undef _POSIX_THREAD_PRIO_INHERIT
|
||||
|
||||
typedef struct binary {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int isFull;
|
||||
}binary;
|
||||
|
||||
typedef struct mutex {
|
||||
pthread_mutexattr_t mutexAttr;
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t waitToBeOwner;
|
||||
#if defined _POSIX_THREAD_PROCESS_SHARED
|
||||
pthread_condattr_t condAttr;
|
||||
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
|
||||
int count;
|
||||
int owned; /* TRUE | FALSE */
|
||||
pthread_t ownerTid;
|
||||
}mutex;
|
||||
|
||||
#define checkStatus(status,message) \
|
||||
if((status)) { \
|
||||
errlogPrintf("%s failed: error %s\n",(message),strerror((status)));}
|
||||
|
||||
#define checkStatusQuit(status,message,method) \
|
||||
if(status) { \
|
||||
errlogPrintf("%s failed: error %s\n",(message),strerror((status))); \
|
||||
cantProceed((method)); \
|
||||
}
|
||||
|
||||
static void convertDoubleToWakeTime(double timeout,struct timespec *wakeTime)
|
||||
{
|
||||
struct timespec wait;
|
||||
TS_STAMP stamp;
|
||||
|
||||
if(timeout<0.0) timeout = 0.0;
|
||||
else if(timeout>3600.0) timeout = 3600.0;
|
||||
tsStampGetCurrent(&stamp);
|
||||
tsStampToTimespec(wakeTime, &stamp);
|
||||
wait.tv_sec = timeout;
|
||||
wait.tv_nsec = (long)((timeout - (double)wait.tv_sec) * 1e9);
|
||||
wakeTime->tv_sec += wait.tv_sec;
|
||||
wakeTime->tv_nsec += wait.tv_nsec;
|
||||
if(wakeTime->tv_nsec>1000000000L) {
|
||||
wakeTime->tv_nsec -= 1000000000L;
|
||||
++wakeTime->tv_sec;
|
||||
}
|
||||
}
|
||||
|
||||
semBinaryId semBinaryCreate(semInitialState initialState)
|
||||
{
|
||||
binary *pbinary;
|
||||
int status;
|
||||
|
||||
pbinary = callocMustSucceed(1,sizeof(binary),"semBinaryCreate");
|
||||
status = pthread_mutex_init(&pbinary->mutex,0);
|
||||
checkStatusQuit(status,"pthread_mutex_init","semBinaryCreate");
|
||||
status = pthread_cond_init(&pbinary->cond,0);
|
||||
checkStatusQuit(status,"pthread_cond_init","semBinaryCreate");
|
||||
if(initialState==semFull) pbinary->isFull = 1;
|
||||
return((semBinaryId)pbinary);
|
||||
}
|
||||
|
||||
semBinaryId semBinaryMustCreate(semInitialState initialState)
|
||||
{
|
||||
semBinaryId id = semBinaryCreate (initialState);
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void semBinaryDestroy(semBinaryId id)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_destroy(&pbinary->mutex);
|
||||
checkStatus(status,"pthread_mutex_destroy");
|
||||
status = pthread_cond_destroy(&pbinary->cond);
|
||||
checkStatus(status,"pthread_cond_destroy");
|
||||
free(pbinary);
|
||||
}
|
||||
|
||||
void semBinaryGive(semBinaryId id)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_lock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semBinaryGive");
|
||||
if(!pbinary->isFull) {
|
||||
pbinary->isFull = 1;
|
||||
status = pthread_cond_signal(&pbinary->cond);
|
||||
checkStatus(status,"pthread_cond_signal");
|
||||
}
|
||||
status = pthread_mutex_unlock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semBinaryGive");
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTake(semBinaryId id)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
int status;
|
||||
|
||||
if(!pbinary) return(semTakeError);
|
||||
status = pthread_mutex_lock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semBinaryTake");
|
||||
/*no need for while since caller must be prepared for no work*/
|
||||
if(!pbinary->isFull) {
|
||||
status = pthread_cond_wait(&pbinary->cond,&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_cond_wait","semBinaryTake");
|
||||
}
|
||||
pbinary->isFull = 0;
|
||||
status = pthread_mutex_unlock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semBinaryTake");
|
||||
return(semTakeOK);
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTakeTimeout(semBinaryId id, double timeout)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
struct timespec wakeTime;
|
||||
int status = 0;
|
||||
int unlockStatus;
|
||||
|
||||
status = pthread_mutex_lock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semBinaryTakeTimeout");
|
||||
if(!pbinary->isFull) {
|
||||
convertDoubleToWakeTime(timeout,&wakeTime);
|
||||
status = pthread_cond_timedwait(
|
||||
&pbinary->cond,&pbinary->mutex,&wakeTime);
|
||||
}
|
||||
if(status==0) pbinary->isFull = 0;
|
||||
unlockStatus = pthread_mutex_unlock(&pbinary->mutex);
|
||||
checkStatusQuit(unlockStatus,"pthread_mutex_unlock","semBinaryTakeTimeout");
|
||||
if(status==0) return(semTakeOK);
|
||||
if(status==ETIMEDOUT) return(semTakeTimeout);
|
||||
checkStatus(status,"pthread_cond_timedwait");
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTakeNoWait(semBinaryId id)
|
||||
{
|
||||
return(semBinaryTakeTimeout(id,0.0));
|
||||
}
|
||||
|
||||
void semBinaryShow(semBinaryId id,unsigned int level)
|
||||
{
|
||||
}
|
||||
|
||||
semMutexId semMutexCreate(void) {
|
||||
mutex *pmutex;
|
||||
int status;
|
||||
|
||||
pmutex = callocMustSucceed(1,sizeof(mutex),"semMutexCreate");
|
||||
status = pthread_mutexattr_init(&pmutex->mutexAttr);
|
||||
checkStatusQuit(status,"pthread_mutexattr_init","semMutexCreate");
|
||||
#if defined _POSIX_THREAD_PRIO_INHERIT
|
||||
status = pthread_mutexattr_setprotocol(
|
||||
&pmutex->mutexAttr,PTHREAD_PRIO_INHERIT);
|
||||
if(errVerbose) checkStatus(status,"pthread_mutexattr_setprotocal");
|
||||
#endif /*_POSIX_THREAD_PRIO_INHERIT*/
|
||||
status = pthread_mutex_init(&pmutex->lock,&pmutex->mutexAttr);
|
||||
checkStatusQuit(status,"pthread_mutex_init","semMutexCreate");
|
||||
#if defined _POSIX_THREAD_PROCESS_SHARED
|
||||
status = pthread_condattr_init(&pmutex->condAttr);
|
||||
checkStatus(status,"pthread_condattr_init");
|
||||
status = pthread_condattr_setpshared(&pmutex->condAttr,
|
||||
PTHREAD_PROCESS_PRIVATE);
|
||||
checkStatus(status,"pthread_condattr_setpshared");
|
||||
status = pthread_cond_init(&pmutex->waitToBeOwner,&pmutex->condAttr);
|
||||
#else
|
||||
status = pthread_cond_init(&pmutex->waitToBeOwner,0);
|
||||
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
|
||||
checkStatusQuit(status,"pthread_cond_init","semMutexCreate");
|
||||
return((semMutexId)pmutex);
|
||||
}
|
||||
|
||||
semMutexId semMutexMustCreate(void)
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void semMutexDestroy(semMutexId id)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
int status;
|
||||
|
||||
status = pthread_cond_destroy(&pmutex->waitToBeOwner);
|
||||
checkStatus(status,"pthread_cond_destroy");
|
||||
#if defined _POSIX_THREAD_PROCESS_SHARED
|
||||
status = pthread_condattr_destroy(&pmutex->condAttr);
|
||||
#endif /*_POSIX_THREAD_PROCESS_SHARED*/
|
||||
status = pthread_mutex_destroy(&pmutex->lock);
|
||||
checkStatus(status,"pthread_mutex_destroy");
|
||||
status = pthread_mutexattr_destroy(&pmutex->mutexAttr);
|
||||
checkStatus(status,"pthread_mutexattr_destroy");
|
||||
free(pmutex);
|
||||
}
|
||||
|
||||
void semMutexGive(semMutexId id)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_lock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semMutexGive");
|
||||
if((pmutex->count<=0) || (pmutex->ownerTid != pthread_self())) {
|
||||
errlogPrintf("semMutexGive but caller is not owner\n");
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semMutexGive");
|
||||
return;
|
||||
}
|
||||
pmutex->count--;
|
||||
if(pmutex->count == 0) {
|
||||
pmutex->owned = 0;
|
||||
pmutex->ownerTid = 0;
|
||||
pthread_cond_signal(&pmutex->waitToBeOwner);
|
||||
}
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semMutexGive");
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTake(semMutexId id)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
pthread_t tid = pthread_self();
|
||||
int status;
|
||||
|
||||
if(!pmutex || !tid) return(semTakeError);
|
||||
status = pthread_mutex_lock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semMutexTake");
|
||||
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid))
|
||||
pthread_cond_wait(&pmutex->waitToBeOwner,&pmutex->lock);
|
||||
pmutex->ownerTid = tid;
|
||||
pmutex->owned = 1;
|
||||
pmutex->count++;
|
||||
status = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semMutexTake");
|
||||
return(semTakeOK);
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeTimeout(semMutexId id, double timeout)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
pthread_t tid = pthread_self();
|
||||
struct timespec wakeTime;
|
||||
int status,unlockStatus;
|
||||
|
||||
convertDoubleToWakeTime(timeout,&wakeTime);
|
||||
status = pthread_mutex_lock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semMutexTakeTimeout");
|
||||
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) {
|
||||
status = pthread_cond_timedwait(
|
||||
&pmutex->waitToBeOwner,&pmutex->lock,&wakeTime);
|
||||
if(!status) break;
|
||||
}
|
||||
if(status==0) {
|
||||
pmutex->ownerTid = tid;
|
||||
pmutex->owned = 1;
|
||||
pmutex->count++;
|
||||
}
|
||||
unlockStatus = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(unlockStatus,"pthread_mutex_lock","semMutexTakeTimeout");
|
||||
if(status==0) return(semTakeOK);
|
||||
if(status==ETIMEDOUT) return(semTakeTimeout);
|
||||
checkStatusQuit(status,"pthread_cond_timedwait","semMutexTakeTimeout");
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeNoWait(semMutexId id)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
pthread_t tid = pthread_self();
|
||||
semTakeStatus status = semTakeError;
|
||||
int pthreadStatus;
|
||||
|
||||
pthreadStatus = pthread_mutex_lock(&pmutex->lock);
|
||||
checkStatusQuit(pthreadStatus,"pthread_mutex_lock","semMutexTakeNoWait");
|
||||
if(!pmutex->owned || pthread_equal(pmutex->ownerTid,tid)) {
|
||||
pmutex->ownerTid = tid;
|
||||
pmutex->owned = 1;
|
||||
pmutex->count++;
|
||||
status = 0;
|
||||
}
|
||||
pthreadStatus = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(pthreadStatus,"pthread_mutex_unlock","semMutexTakeNoWait");
|
||||
return(status);
|
||||
}
|
||||
|
||||
void semMutexShow(semMutexId id,unsigned int level)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
printf("ownerTid %p count %d owned %d\n",
|
||||
pmutex->ownerTid,pmutex->count,pmutex->owned);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
/* for a pure posix implementation no osdSem.h definitions are needed*/
|
||||
@@ -22,7 +22,8 @@ of this distribution.
|
||||
|
||||
#include "ellLib.h"
|
||||
#include "osiThread.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "cantProceed.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAssert.h"
|
||||
@@ -46,15 +47,15 @@ typedef struct threadInfo {
|
||||
struct sched_param schedParam;
|
||||
THREADFUNC createFunc;
|
||||
void *createArg;
|
||||
semBinaryId suspendSem;
|
||||
epicsEventId suspendEvent;
|
||||
int isSuspended;
|
||||
unsigned int osiPriority;
|
||||
char *name;
|
||||
} threadInfo;
|
||||
|
||||
static pthread_key_t getpthreadInfo;
|
||||
static semMutexId onceMutex;
|
||||
static semMutexId listMutex;
|
||||
static epicsMutexId onceLock;
|
||||
static epicsMutexId listLock;
|
||||
static ELLLIST pthreadList;
|
||||
static commonAttr *pcommonAttr = 0;
|
||||
static int threadInitCalled = 0;
|
||||
@@ -97,7 +98,7 @@ static void myAtExit(void)
|
||||
fprintf(stderr,"osdThread myAtExit extered multiple times\n");
|
||||
return;
|
||||
}
|
||||
semMutexMustTake(listMutex);
|
||||
epicsMutexMustLock(listLock);
|
||||
pthreadInfo=(threadInfo *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
if(pthreadInfo->createFunc){/* dont cancel main thread*/
|
||||
@@ -105,11 +106,11 @@ static void myAtExit(void)
|
||||
}
|
||||
pthreadInfo=(threadInfo *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
semMutexGive(listMutex);
|
||||
epicsMutexUnlock(listLock);
|
||||
/* delete all resources created by once */
|
||||
free(pcommonAttr); pcommonAttr=0;
|
||||
semMutexDestroy(listMutex);
|
||||
semMutexDestroy(onceMutex);
|
||||
epicsMutexDestroy(listLock);
|
||||
epicsMutexDestroy(onceLock);
|
||||
pthread_key_delete(getpthreadInfo);
|
||||
}
|
||||
|
||||
@@ -168,7 +169,7 @@ static threadInfo * init_threadInfo(const char *name,
|
||||
&pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED);
|
||||
if(errVerbose) checkStatusOnce(status,"pthread_attr_setinheritsched");
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
pthreadInfo->suspendSem = semBinaryMustCreate(semEmpty);
|
||||
pthreadInfo->suspendEvent = epicsEventMustCreate(epicsEventEmpty);
|
||||
pthreadInfo->name = mallocMustSucceed(strlen(name)+1,"threadCreate");
|
||||
strcpy(pthreadInfo->name,name);
|
||||
return(pthreadInfo);
|
||||
@@ -178,10 +179,10 @@ static void free_threadInfo(threadInfo *pthreadInfo)
|
||||
{
|
||||
int status;
|
||||
|
||||
semMutexMustTake(listMutex);
|
||||
epicsMutexMustLock(listLock);
|
||||
ellDelete(&pthreadList,&pthreadInfo->node);
|
||||
semMutexGive(listMutex);
|
||||
semBinaryDestroy(pthreadInfo->suspendSem);
|
||||
epicsMutexUnlock(listLock);
|
||||
epicsEventDestroy(pthreadInfo->suspendEvent);
|
||||
status = pthread_attr_destroy(&pthreadInfo->attr);
|
||||
checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo");
|
||||
free(pthreadInfo->name);
|
||||
@@ -194,8 +195,8 @@ static void once(void)
|
||||
int status;
|
||||
|
||||
pthread_key_create(&getpthreadInfo,0);
|
||||
onceMutex = semMutexMustCreate();
|
||||
listMutex = semMutexMustCreate();
|
||||
onceLock = epicsMutexMustCreate();
|
||||
listLock = epicsMutexMustCreate();
|
||||
ellInit(&pthreadList);
|
||||
pcommonAttr = calloc(1,sizeof(commonAttr));
|
||||
if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","threadInit");
|
||||
@@ -231,10 +232,10 @@ static void once(void)
|
||||
pthreadInfo = init_threadInfo("_main_",0,0,0,0);
|
||||
status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
|
||||
checkStatusOnceQuit(status,"pthread_setspecific","threadInit");
|
||||
status = semMutexTake(listMutex);
|
||||
checkStatusOnceQuit(status,"semMutexTake","threadInit");
|
||||
status = epicsMutexLock(listLock);
|
||||
checkStatusOnceQuit(status,"epicsMutexLock","threadInit");
|
||||
ellAdd(&pthreadList,&pthreadInfo->node);
|
||||
semMutexGive(listMutex);
|
||||
epicsMutexUnlock(listLock);
|
||||
status = atexit(myAtExit);
|
||||
checkStatusOnce(status,"atexit");
|
||||
}
|
||||
@@ -248,9 +249,9 @@ static void * start_routine(void *arg)
|
||||
checkStatusQuit(status,"pthread_setspecific","start_routine");
|
||||
status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
|
||||
checkStatusQuit(status,"pthread_setcanceltype","start_routine");
|
||||
semMutexMustTake(listMutex);
|
||||
epicsMutexMustLock(listLock);
|
||||
ellAdd(&pthreadList,&pthreadInfo->node);
|
||||
semMutexGive(listMutex);
|
||||
epicsMutexUnlock(listLock);
|
||||
|
||||
(*pthreadInfo->createFunc)(pthreadInfo->createArg);
|
||||
|
||||
@@ -302,8 +303,8 @@ void threadOnceOsd(threadOnceId *id, void (*func)(void *), void *arg)
|
||||
{
|
||||
|
||||
if(!threadInitCalled) threadInit();
|
||||
if(semMutexTake(onceMutex) != semTakeOK) {
|
||||
fprintf(stderr,"threadOnceOsd semMutexTake failed.\n");
|
||||
if(epicsMutexLock(onceLock) != epicsMutexLockOK) {
|
||||
fprintf(stderr,"threadOnceOsd epicsMutexLock failed.\n");
|
||||
fprintf(stderr,"Did you call threadInit? Program exiting\n");
|
||||
exit(-1);
|
||||
}
|
||||
@@ -312,7 +313,7 @@ void threadOnceOsd(threadOnceId *id, void (*func)(void *), void *arg)
|
||||
func(arg);
|
||||
*id = +1; /* +1 => func() done (see threadOnce() macro defn) */
|
||||
}
|
||||
semMutexGive(onceMutex);
|
||||
epicsMutexUnlock(onceLock);
|
||||
}
|
||||
|
||||
threadId threadCreate(const char *name,
|
||||
@@ -335,14 +336,14 @@ void threadSuspendSelf(void)
|
||||
{
|
||||
threadInfo *pthreadInfo = (threadInfo *)pthread_getspecific(getpthreadInfo);
|
||||
pthreadInfo->isSuspended = 1;
|
||||
semBinaryMustTake(pthreadInfo->suspendSem);
|
||||
epicsEventMustWait(pthreadInfo->suspendEvent);
|
||||
}
|
||||
|
||||
void threadResume(threadId id)
|
||||
{
|
||||
threadInfo *pthreadInfo = (threadInfo *)id;
|
||||
pthreadInfo->isSuspended = 0;
|
||||
semBinaryGive(pthreadInfo->suspendSem);
|
||||
epicsEventSignal(pthreadInfo->suspendEvent);
|
||||
}
|
||||
|
||||
void threadExitMain(void)
|
||||
@@ -454,13 +455,13 @@ threadId threadGetIdSelf(void) {
|
||||
|
||||
threadId threadGetId(const char *name) {
|
||||
threadInfo *pthreadInfo;
|
||||
semMutexMustTake(listMutex);
|
||||
epicsMutexMustLock(listLock);
|
||||
pthreadInfo=(threadInfo *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
if(strcmp(name,pthreadInfo->name) == 0) break;
|
||||
pthreadInfo=(threadInfo *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
semMutexGive(listMutex);
|
||||
epicsMutexUnlock(listLock);
|
||||
return((threadId)pthreadInfo);
|
||||
}
|
||||
|
||||
@@ -481,13 +482,13 @@ void threadShowAll(unsigned int level)
|
||||
{
|
||||
threadInfo *pthreadInfo;
|
||||
threadShow(0,level);
|
||||
semMutexMustTake(listMutex);
|
||||
epicsMutexMustLock(listLock);
|
||||
pthreadInfo=(threadInfo *)ellFirst(&pthreadList);
|
||||
while(pthreadInfo) {
|
||||
threadShow((threadId)pthreadInfo,level);
|
||||
pthreadInfo=(threadInfo *)ellNext(&pthreadInfo->node);
|
||||
}
|
||||
semMutexGive(listMutex);
|
||||
epicsMutexUnlock(listLock);
|
||||
}
|
||||
|
||||
void threadShow(threadId id,unsigned int level)
|
||||
|
||||
@@ -25,7 +25,7 @@ of this distribution.
|
||||
#include "cantProceed.h"
|
||||
#include "errlog.h"
|
||||
#include "osiThread.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "tsStamp.h"
|
||||
#include "iocClock.h"
|
||||
|
||||
@@ -36,7 +36,7 @@ static int iocClockGetCurrent(TS_STAMP *pDest);
|
||||
static int iocClockGetEvent(TS_STAMP *pDest, unsigned eventNumber);
|
||||
|
||||
typedef struct iocClockPvt {
|
||||
semMutexId lock;
|
||||
epicsMutexId lock;
|
||||
TS_STAMP clock;
|
||||
unsigned long lastTick;
|
||||
epicsUInt32 nanosecondsPerTick;
|
||||
@@ -76,7 +76,7 @@ static void syncNTP(void)
|
||||
prevStatusBad = 0;
|
||||
}
|
||||
tsStampFromTimespec(&epicsTime,&Currtime);
|
||||
semMutexMustTake(piocClockPvt->lock);
|
||||
epicsMutexMustLock(piocClockPvt->lock);
|
||||
diffTime = tsStampDiffInSeconds(&epicsTime,&piocClockPvt->clock);
|
||||
if(diffTime>=0.0) {
|
||||
piocClockPvt->clock = epicsTime;
|
||||
@@ -84,7 +84,7 @@ static void syncNTP(void)
|
||||
piocClockPvt->ticksToSkip = (int) (diffTime*piocClockPvt->tickRate);
|
||||
}
|
||||
piocClockPvt->lastTick = tickGet();
|
||||
semMutexGive(piocClockPvt->lock);
|
||||
epicsMutexUnlock(piocClockPvt->lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void iocClockInit()
|
||||
{
|
||||
if(piocClockPvt) return;
|
||||
piocClockPvt = callocMustSucceed(1,sizeof(iocClockPvt),"iocClockInit");
|
||||
piocClockPvt->lock = semMutexMustCreate();
|
||||
piocClockPvt->lock = epicsMutexCreate();
|
||||
piocClockPvt->nanosecondsPerTick = BILLION/sysClkRateGet();
|
||||
piocClockPvt->tickRate = sysClkRateGet();
|
||||
piocClockPvt->getCurrent = iocClockGetCurrent;
|
||||
@@ -133,7 +133,7 @@ int iocClockGetCurrent(TS_STAMP *pDest)
|
||||
{
|
||||
unsigned long currentTick,nticks,nsecs;
|
||||
|
||||
semMutexMustTake(piocClockPvt->lock);
|
||||
epicsMutexMustLock(piocClockPvt->lock);
|
||||
currentTick = tickGet();
|
||||
while(currentTick!=piocClockPvt->lastTick) {
|
||||
nticks = (currentTick>piocClockPvt->lastTick)
|
||||
@@ -157,7 +157,7 @@ int iocClockGetCurrent(TS_STAMP *pDest)
|
||||
piocClockPvt->clock.secPastEpoch += nsecs;
|
||||
}
|
||||
*pDest = piocClockPvt->clock;
|
||||
semMutexGive(piocClockPvt->lock);
|
||||
epicsMutexUnlock(piocClockPvt->lock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/* os/vxWorks/osdSem.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 25AUG99 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
#include <time.h>
|
||||
#include <objLib.h>
|
||||
#include <sysLib.h>
|
||||
/* The following not defined in an vxWorks header */
|
||||
int sysClkRateGet(void);
|
||||
|
||||
|
||||
#include "osiSem.h"
|
||||
|
||||
semBinaryId semBinaryCreate(semInitialState initialState)
|
||||
{
|
||||
return((semBinaryId)semBCreate(
|
||||
SEM_Q_FIFO,((initialState==semEmpty) ? SEM_EMPTY : SEM_FULL)));
|
||||
}
|
||||
|
||||
semBinaryId semBinaryMustCreate(semInitialState initialState)
|
||||
{
|
||||
semBinaryId id = semBinaryCreate (initialState);
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void semBinaryDestroy(semBinaryId id)
|
||||
{
|
||||
semDelete((SEM_ID)id);
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTakeTimeout(
|
||||
semBinaryId id, double timeOut)
|
||||
{
|
||||
int status;
|
||||
int ticks;
|
||||
ticks = (int)(timeOut * (double)sysClkRateGet());
|
||||
if(ticks<=0) ticks = 1;
|
||||
status = semTake((SEM_ID)id,ticks);
|
||||
if(status==OK) return(semTakeOK);
|
||||
if(errno==S_objLib_OBJ_TIMEOUT) return(semTakeTimeout);
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTakeNoWait(semBinaryId id)
|
||||
{
|
||||
int status;
|
||||
status = semTake((SEM_ID)id,NO_WAIT);
|
||||
if(status==OK) return(semTakeOK);
|
||||
if(errno==S_objLib_OBJ_UNAVAILABLE) return(semTakeTimeout);
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
void semBinaryShow(semBinaryId id,unsigned int level)
|
||||
{
|
||||
semShow((SEM_ID)id,level);
|
||||
}
|
||||
|
||||
semMutexId semMutexCreate(void)
|
||||
{
|
||||
return((semMutexId)
|
||||
semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY));
|
||||
}
|
||||
|
||||
semMutexId semMutexMustCreate(void)
|
||||
{
|
||||
semMutexId id = semMutexCreate ();
|
||||
assert (id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void semMutexDestroy(semMutexId id)
|
||||
{
|
||||
semDelete((SEM_ID)id);
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeTimeout(
|
||||
semMutexId id, double timeOut)
|
||||
{
|
||||
int status;
|
||||
int ticks;
|
||||
ticks = (int)(timeOut * (double)sysClkRateGet());
|
||||
if(ticks<=0) ticks = 1;
|
||||
status = semTake((SEM_ID)id,ticks);
|
||||
if(status==OK) return(semTakeOK);
|
||||
if(errno==S_objLib_OBJ_TIMEOUT) return(semTakeTimeout);
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
semTakeStatus semMutexTakeNoWait(semMutexId id)
|
||||
{
|
||||
int status;
|
||||
status = semTake((SEM_ID)id,NO_WAIT);
|
||||
if(status==OK) return(semTakeOK);
|
||||
if(errno==S_objLib_OBJ_UNAVAILABLE) return(semTakeTimeout);
|
||||
return(semTakeError);
|
||||
}
|
||||
|
||||
void semMutexShow(semMutexId id,unsigned int level)
|
||||
{
|
||||
semShow((SEM_ID)id,level);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/* os/vxWorks/osdSem.h */
|
||||
|
||||
/* Author: Marty Kraimer Date: 25AUG99 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
|
||||
/* If the macro is replaced by inline it is necessary to say
|
||||
static __inline__
|
||||
but then a warning message appears everywhere osdSem.h is included
|
||||
*/
|
||||
|
||||
#define semBinaryGive(ID) semGive((SEM_ID)(ID))
|
||||
|
||||
#define semBinaryTake(ID) \
|
||||
(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? semTakeOK : semTakeError)
|
||||
|
||||
#define semMutexGive(ID) semGive((SEM_ID)(ID))
|
||||
|
||||
#define semMutexTake(ID) \
|
||||
(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? semTakeOK : semTakeError)
|
||||
@@ -1,52 +0,0 @@
|
||||
#ifndef osiSemh
|
||||
#define osiSemh
|
||||
|
||||
#include "epicsAssert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
typedef void *semBinaryId;
|
||||
typedef enum {semTakeOK,semTakeTimeout,semTakeError} semTakeStatus;
|
||||
typedef enum {semEmpty,semFull} semInitialState;
|
||||
|
||||
epicsShareFunc semBinaryId epicsShareAPI semBinaryCreate(
|
||||
semInitialState initialState);
|
||||
epicsShareFunc semBinaryId epicsShareAPI semBinaryMustCreate (
|
||||
semInitialState initialState);
|
||||
epicsShareFunc void epicsShareAPI semBinaryDestroy(semBinaryId id);
|
||||
epicsShareFunc void epicsShareAPI semBinaryGive(semBinaryId id);
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTake(semBinaryId id);
|
||||
#define semBinaryMustTake(ID) assert((semBinaryTake ((ID))==semTakeOK))
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeTimeout(
|
||||
semBinaryId id, double timeOut);
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeNoWait(semBinaryId id);
|
||||
epicsShareFunc void epicsShareAPI semBinaryShow(semBinaryId id, unsigned int level);
|
||||
|
||||
typedef void *semMutexId;
|
||||
epicsShareFunc semMutexId epicsShareAPI semMutexCreate(void);
|
||||
epicsShareFunc semMutexId epicsShareAPI semMutexMustCreate (void);
|
||||
epicsShareFunc void epicsShareAPI semMutexDestroy(semMutexId id);
|
||||
epicsShareFunc void epicsShareAPI semMutexGive(semMutexId id);
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake(semMutexId id);
|
||||
#define semMutexMustTake(ID) assert((semMutexTake((ID))==semTakeOK))
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout(
|
||||
semMutexId id, double timeOut);
|
||||
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait(semMutexId id);
|
||||
epicsShareFunc void epicsShareAPI semMutexShow(semMutexId id,unsigned int level);
|
||||
|
||||
/*NOTES:
|
||||
Mutex semaphores MUST implement recursive locking
|
||||
Mutex semaphores should implement priority inheritance and deletion safe
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "osdSem.h"
|
||||
|
||||
#endif /* osiSemh */
|
||||
@@ -25,7 +25,7 @@ of this distribution.
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbDefs.h"
|
||||
#include "osiThread.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "errlog.h"
|
||||
#include "ellLib.h"
|
||||
#include "errMdef.h"
|
||||
@@ -46,9 +46,9 @@ struct task_list {
|
||||
|
||||
static ELLLIST list;
|
||||
static ELLLIST anylist;
|
||||
static semMutexId lock;
|
||||
static semMutexId anylock;
|
||||
static semMutexId alloclock;
|
||||
static epicsMutexId lock;
|
||||
static epicsMutexId anylock;
|
||||
static epicsMutexId alloclock;
|
||||
static threadId taskwdid=0;
|
||||
volatile int taskwdOn=TRUE;
|
||||
struct freeList{
|
||||
@@ -66,9 +66,9 @@ static void taskwdInitPvt(void *);
|
||||
|
||||
static void taskwdInitPvt(void *arg)
|
||||
{
|
||||
lock = semMutexMustCreate();
|
||||
anylock = semMutexMustCreate();
|
||||
alloclock = semMutexMustCreate();
|
||||
lock = epicsMutexMustCreate();
|
||||
anylock = epicsMutexMustCreate();
|
||||
alloclock = epicsMutexMustCreate();
|
||||
ellInit(&list);
|
||||
ellInit(&anylist);
|
||||
taskwdid = threadCreate(
|
||||
@@ -88,14 +88,14 @@ void epicsShareAPI taskwdInsert(threadId tid,TASKWDFUNCPRR callback,void *arg)
|
||||
struct task_list *pt;
|
||||
|
||||
taskwdInit();
|
||||
semMutexMustTake(lock);
|
||||
epicsMutexMustLock(lock);
|
||||
pt = allocList();
|
||||
ellAdd(&list,(void *)pt);
|
||||
pt->suspended = FALSE;
|
||||
pt->id.tid = tid;
|
||||
pt->callback = callback;
|
||||
pt->arg = arg;
|
||||
semMutexGive(lock);
|
||||
epicsMutexUnlock(lock);
|
||||
}
|
||||
|
||||
void epicsShareAPI taskwdAnyInsert(void *userpvt,TASKWDANYFUNCPRR callback,void *arg)
|
||||
@@ -103,13 +103,13 @@ void epicsShareAPI taskwdAnyInsert(void *userpvt,TASKWDANYFUNCPRR callback,void
|
||||
struct task_list *pt;
|
||||
|
||||
taskwdInit();
|
||||
semMutexMustTake(anylock);
|
||||
epicsMutexMustLock(anylock);
|
||||
pt = allocList();
|
||||
ellAdd(&anylist,(void *)pt);
|
||||
pt->id.userpvt = userpvt;
|
||||
pt->callback = callback;
|
||||
pt->arg = arg;
|
||||
semMutexGive(anylock);
|
||||
epicsMutexUnlock(anylock);
|
||||
}
|
||||
|
||||
void epicsShareAPI taskwdRemove(threadId tid)
|
||||
@@ -117,18 +117,18 @@ void epicsShareAPI taskwdRemove(threadId tid)
|
||||
struct task_list *pt;
|
||||
|
||||
taskwdInit();
|
||||
semMutexMustTake(lock);
|
||||
epicsMutexMustLock(lock);
|
||||
pt = (struct task_list *)ellFirst(&list);
|
||||
while(pt!=NULL) {
|
||||
if (tid == pt->id.tid) {
|
||||
ellDelete(&list,(void *)pt);
|
||||
freeList(pt);
|
||||
semMutexGive(lock);
|
||||
epicsMutexUnlock(lock);
|
||||
return;
|
||||
}
|
||||
pt = (struct task_list *)ellNext((ELLNODE *)pt);
|
||||
}
|
||||
semMutexGive(lock);
|
||||
epicsMutexUnlock(lock);
|
||||
errMessage(-1,"taskwdRemove failed");
|
||||
}
|
||||
|
||||
@@ -137,18 +137,18 @@ void epicsShareAPI taskwdAnyRemove(void *userpvt)
|
||||
struct task_list *pt;
|
||||
|
||||
taskwdInit();
|
||||
semMutexMustTake(anylock);
|
||||
epicsMutexMustLock(anylock);
|
||||
pt = (struct task_list *)ellFirst(&anylist);
|
||||
while(pt!=NULL) {
|
||||
if (userpvt == pt->id.userpvt) {
|
||||
ellDelete(&anylist,(void *)pt);
|
||||
freeList(pt);
|
||||
semMutexGive(anylock);
|
||||
epicsMutexUnlock(anylock);
|
||||
return;
|
||||
}
|
||||
pt = (struct task_list *)ellNext((void *)pt);
|
||||
}
|
||||
semMutexGive(anylock);
|
||||
epicsMutexUnlock(anylock);
|
||||
errMessage(-1,"taskwdanyRemove failed");
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ static void taskwdTask(void)
|
||||
|
||||
while(TRUE) {
|
||||
if(taskwdOn) {
|
||||
semMutexMustTake(lock);
|
||||
epicsMutexMustLock(lock);
|
||||
pt = (struct task_list *)ellFirst(&list);
|
||||
while(pt) {
|
||||
next = (struct task_list *)ellNext((void *)pt);
|
||||
@@ -184,7 +184,7 @@ static void taskwdTask(void)
|
||||
void *arg = pt->arg;
|
||||
|
||||
/*Must allow callback to call taskwdRemove*/
|
||||
semMutexGive(lock);
|
||||
epicsMutexUnlock(lock);
|
||||
(pcallback)(arg);
|
||||
/*skip rest because we have unlocked*/
|
||||
break;
|
||||
@@ -195,7 +195,7 @@ static void taskwdTask(void)
|
||||
}
|
||||
pt = next;
|
||||
}
|
||||
semMutexGive(lock);
|
||||
epicsMutexUnlock(lock);
|
||||
}
|
||||
threadSleep(TASKWD_DELAY);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ static struct task_list *allocList(void)
|
||||
{
|
||||
struct task_list *pt;
|
||||
|
||||
semMutexMustTake(alloclock);
|
||||
epicsMutexMustLock(alloclock);
|
||||
if(freeHead) {
|
||||
pt = (struct task_list *)freeHead;
|
||||
freeHead = freeHead->next;
|
||||
@@ -214,15 +214,15 @@ static struct task_list *allocList(void)
|
||||
errMessage(0,"taskwd failed on call to calloc\n");
|
||||
exit(1);
|
||||
}
|
||||
semMutexGive(alloclock);
|
||||
epicsMutexUnlock(alloclock);
|
||||
return(pt);
|
||||
}
|
||||
|
||||
static void freeList(struct task_list *pt)
|
||||
{
|
||||
|
||||
semMutexMustTake(alloclock);
|
||||
epicsMutexMustLock(alloclock);
|
||||
((struct freeList *)pt)->next = freeHead;
|
||||
freeHead = (struct freeList *)pt;
|
||||
semMutexGive(alloclock);
|
||||
epicsMutexUnlock(alloclock);
|
||||
}
|
||||
|
||||
@@ -14,16 +14,6 @@ ringPointerTestHost_SRCS += ringPointerTestMain.c ringPointerTest.c
|
||||
PROD += ringPointerTestHost
|
||||
OBJS_IOC += ringPointerTest
|
||||
|
||||
# Marty remover the following
|
||||
semBinaryTestHost_SRCS += semBinaryTestMain.c semBinaryTest.c
|
||||
PROD += semBinaryTestHost
|
||||
OBJS_IOC += semBinaryTest
|
||||
|
||||
# Marty remover the following
|
||||
semMutexTestHost_SRCS += semMutexTestMain.c semMutexTest.c
|
||||
PROD += semMutexTestHost
|
||||
OBJS_IOC += semMutexTest
|
||||
|
||||
epicsEventTestHost_SRCS += epicsEventTestMain.cpp epicsEventTest.cpp
|
||||
PROD += epicsEventTestHost
|
||||
OBJS_IOC += epicsEventTest
|
||||
|
||||
@@ -19,12 +19,12 @@ of this distribution.
|
||||
#include "osiThread.h"
|
||||
#include "epicsRingPointer.h"
|
||||
#include "errlog.h"
|
||||
#include "osiSem.h"
|
||||
#include "epicsEvent.h"
|
||||
|
||||
#define ringSize 10
|
||||
|
||||
typedef struct info {
|
||||
semBinaryId consumerEvent;
|
||||
epicsEventId consumerEvent;
|
||||
epicsRingPointerId ring;
|
||||
}info;
|
||||
|
||||
@@ -36,8 +36,7 @@ static void consumer(void *arg)
|
||||
|
||||
printf("consumer starting\n");
|
||||
while(1) {
|
||||
semTakeStatus status;
|
||||
status = semBinaryTake(pinfo->consumerEvent);
|
||||
epicsEventMustWait(pinfo->consumerEvent);
|
||||
while((newvalue = (int *)epicsRingPointerPop(pinfo->ring))) {
|
||||
if(expectedValue != *newvalue) {
|
||||
printf("consumer expected %d got %d\n",
|
||||
@@ -52,15 +51,15 @@ void ringPointerTest()
|
||||
{
|
||||
int i;
|
||||
info *pinfo;
|
||||
semBinaryId consumerEvent;
|
||||
epicsEventId consumerEvent;
|
||||
int value[ringSize*2];
|
||||
int *pgetValue;
|
||||
epicsRingPointerId ring;
|
||||
|
||||
for(i=0; i<ringSize*2; i++) value[i] = i;
|
||||
pinfo = calloc(1,sizeof(info));
|
||||
pinfo->consumerEvent = consumerEvent = semBinaryMustCreate(semEmpty);
|
||||
if(!consumerEvent) {printf("semBinaryMustCreate failed\n");exit(1);}
|
||||
pinfo->consumerEvent = consumerEvent = epicsEventMustCreate(epicsEventEmpty);
|
||||
if(!consumerEvent) {printf("epicsEventMustCreate failed\n");exit(1);}
|
||||
pinfo->ring = ring = epicsRingPointerCreate(ringSize);
|
||||
if(!ring) {printf("epicsRingPointerCreate failed\n");exit(1);}
|
||||
threadCreate("consumer",50,threadGetStackSize(threadStackSmall),
|
||||
@@ -83,12 +82,12 @@ void ringPointerTest()
|
||||
if(!epicsRingPointerIsEmpty(ring)) printf("epicsRingPointerIsEmpty failed\n");
|
||||
for(i=0; i<ringSize*2; i++) {
|
||||
while(epicsRingPointerIsFull(ring)) {
|
||||
semBinaryGive(consumerEvent);
|
||||
epicsEventSignal(consumerEvent);
|
||||
threadSleep(2.0);
|
||||
}
|
||||
if(!epicsRingPointerPush(ring,(void *)&value[i]))
|
||||
printf("Why is ring full\n");
|
||||
}
|
||||
semBinaryGive(consumerEvent);
|
||||
epicsEventSignal(consumerEvent);
|
||||
threadSleep(2.0);
|
||||
}
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
/* semBinaryTest.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "osiThread.h"
|
||||
#include "epicsRingPointer.h"
|
||||
#include "errlog.h"
|
||||
#include "osiSem.h"
|
||||
|
||||
|
||||
typedef struct info {
|
||||
semBinaryId binary;
|
||||
semMutexId lockRing;
|
||||
int quit;
|
||||
epicsRingPointerId ring;
|
||||
}info;
|
||||
|
||||
static void consumer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
threadId idSelf = threadGetIdSelf();
|
||||
|
||||
printf("consumer %p starting time %ld\n",idSelf,time(&tp));
|
||||
while(1) {
|
||||
semTakeStatus status;
|
||||
if(pinfo->quit) {
|
||||
printf("consumer %p returning time %ld\n",
|
||||
idSelf,time(&tp));
|
||||
return;
|
||||
}
|
||||
status = semBinaryTake(pinfo->binary);
|
||||
if(status!=semTakeOK) {
|
||||
printf("task %p semBinaryTake returned %d time %ld\n",
|
||||
idSelf,(int)status,time(&tp));
|
||||
}
|
||||
while(epicsRingPointerGetUsed(pinfo->ring)>=2) {
|
||||
threadId message[2];
|
||||
int i;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(!(message[i]=epicsRingPointerPop(pinfo->ring)))
|
||||
printf("consumer error\n");
|
||||
}
|
||||
if(message[0]!=message[1]) {
|
||||
printf("consumer error message %p %p\n",message[0],message[1]);
|
||||
} else {
|
||||
printf("consumer message from %p\n",message[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void producer(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
threadId idSelf = threadGetIdSelf();
|
||||
int ntimes=0;
|
||||
|
||||
printf("producer %p starting time %ld\n",idSelf,time(&tp));
|
||||
while(1) {
|
||||
semTakeStatus status;
|
||||
|
||||
++ntimes;
|
||||
if(pinfo->quit) {
|
||||
printf("producer %p returning time %ld\n",
|
||||
idSelf,time(&tp));
|
||||
return;
|
||||
}
|
||||
status = semMutexTake(pinfo->lockRing);
|
||||
if(status!=semTakeOK) {
|
||||
printf("producer %p semMutexTake returned %d time %ld\n",
|
||||
idSelf,(int)status,time(&tp));
|
||||
}
|
||||
if(epicsRingPointerGetFree(pinfo->ring)>=2) {
|
||||
int i;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(!epicsRingPointerPush(pinfo->ring,idSelf))
|
||||
printf("producer %p error\n",idSelf);
|
||||
if(i==0 && (ntimes%4==0)) threadSleep(.1);
|
||||
}
|
||||
printf("producer %p sending\n",idSelf);
|
||||
} else {
|
||||
printf("producer %p ring buffer is full\n",idSelf);
|
||||
}
|
||||
semMutexGive(pinfo->lockRing);
|
||||
threadSleep(1.0);
|
||||
semBinaryGive(pinfo->binary);
|
||||
}
|
||||
}
|
||||
|
||||
void semBinaryTest(int nthreads,int verbose)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
threadId *id;
|
||||
char **name;
|
||||
int i;
|
||||
info *pinfo;
|
||||
semBinaryId binary;
|
||||
int status;
|
||||
time_t tp;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
threadInit ();
|
||||
errVerbose = verbose;
|
||||
binary = semBinaryMustCreate(semEmpty);
|
||||
printf("calling semBinaryTakeTimeout(binary,2.0) time %ld\n",time(&tp));
|
||||
status = semBinaryTakeTimeout(binary,2.0);
|
||||
if(status!=semTakeTimeout) printf("status %d\n",status);
|
||||
printf("calling semBinaryTakeNoWait(binary) time %ld\n",time(&tp));
|
||||
status = semBinaryTakeNoWait(binary);
|
||||
if(status!=semTakeTimeout) printf("status %d\n",status);
|
||||
printf("calling semBinaryGive() time %ld\n",time(&tp));
|
||||
semBinaryGive(binary);
|
||||
printf("calling semBinaryTakeTimeout(binary,2.0) time %ld\n",time(&tp));
|
||||
status = semBinaryTakeTimeout(binary,2.0);
|
||||
if(status) printf("status %d\n",status);
|
||||
printf("calling semBinaryGive() time %ld\n",time(&tp));
|
||||
semBinaryGive(binary);
|
||||
printf("calling semBinaryTakeNoWait(binary) time %ld\n",time(&tp));
|
||||
status = semBinaryTakeNoWait(binary);
|
||||
if(status) printf("status %d\n",status);
|
||||
|
||||
if(nthreads<=0) {
|
||||
errVerbose = errVerboseSave;
|
||||
return;
|
||||
}
|
||||
pinfo = calloc(1,sizeof(info));
|
||||
pinfo->binary = binary;
|
||||
pinfo->lockRing = semMutexMustCreate();
|
||||
pinfo->ring = epicsRingPointerCreate(1024*2);
|
||||
stackSize = threadGetStackSize(threadStackSmall);
|
||||
threadCreate("consumer",50,stackSize,consumer,pinfo);
|
||||
id = calloc(nthreads,sizeof(threadId));
|
||||
name = calloc(nthreads,sizeof(char *));
|
||||
for(i=0; i<nthreads; i++) {
|
||||
name[i] = calloc(10,sizeof(char));
|
||||
sprintf(name[i],"producer%d",i);
|
||||
id[i] = threadCreate(name[i],40,stackSize,producer,pinfo);
|
||||
printf("created producer %d id %p time %ld\n",
|
||||
i, id[i],time(&tp));
|
||||
}
|
||||
threadSleep(5.0);
|
||||
printf("semTest setting quit time %ld\n",time(&tp));
|
||||
pinfo->quit = 1;
|
||||
threadSleep(2.0);
|
||||
semBinaryGive(pinfo->binary);
|
||||
threadSleep(1.0);
|
||||
printf("semTest returning time %ld\n",time(&tp));
|
||||
errVerbose = errVerboseSave;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/* semBinaryTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "osiThread.h"
|
||||
void semBinaryTest(int nthreads,int errVerbose);
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int nthreads = 2;
|
||||
int errVerbose = 0;
|
||||
|
||||
if(argc>1) {
|
||||
if(isdigit(*argv[1])) {
|
||||
sscanf(argv[1],"%d",&nthreads);
|
||||
printf("nthreads %d\n",nthreads);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(argc>2) {
|
||||
if(isdigit(*argv[2])) {
|
||||
sscanf(argv[2],"%d",&errVerbose);
|
||||
printf("errVerbose %d\n",errVerbose);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
semBinaryTest(nthreads,errVerbose);
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/* semMutexTest.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "osiThread.h"
|
||||
#include "errlog.h"
|
||||
#include "osiSem.h"
|
||||
|
||||
typedef struct info {
|
||||
int threadnum;
|
||||
semMutexId mutex;
|
||||
int quit;
|
||||
}info;
|
||||
|
||||
static void mutexThread(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
printf("mutexThread %d starting time %ld\n",pinfo->threadnum,time(&tp));
|
||||
while(1) {
|
||||
semTakeStatus status;
|
||||
if(pinfo->quit) {
|
||||
printf("mutexThread %d returning time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
return;
|
||||
}
|
||||
status = semMutexTake(pinfo->mutex);
|
||||
if(status!=semTakeOK) {
|
||||
printf("task %d semMutexTake returned %d time %ld\n",
|
||||
pinfo->threadnum,(int)status,time(&tp));
|
||||
}
|
||||
printf("mutexThread %d semMutexTake time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
threadSleep(.1);
|
||||
semMutexGive(pinfo->mutex);
|
||||
threadSleep(.9);
|
||||
}
|
||||
}
|
||||
|
||||
void semMutexTest(int nthreads,int verbose)
|
||||
{
|
||||
unsigned int stackSize;
|
||||
threadId *id;
|
||||
int i;
|
||||
char **name;
|
||||
void **arg;
|
||||
info **pinfo;
|
||||
semMutexId mutex;
|
||||
int status;
|
||||
time_t tp;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
threadInit ();
|
||||
errVerbose = verbose;
|
||||
mutex = semMutexMustCreate();
|
||||
printf("calling semMutexTake(mutex) time %ld\n",time(&tp));
|
||||
status = semMutexTake(mutex);
|
||||
if(status) printf("status %d\n",status);
|
||||
printf("calling semMutexTakeTimeout(mutex,2.0) time %ld\n",time(&tp));
|
||||
status = semMutexTakeTimeout(mutex,2.0);
|
||||
if(status) printf("status %d\n",status);
|
||||
printf("calling semMutexTakeNoWait(mutex) time %ld\n",time(&tp));
|
||||
status = semMutexTakeNoWait(mutex);
|
||||
if(status) printf("status %d\n",status);
|
||||
semMutexShow(mutex,1);
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
semMutexShow(mutex,1);
|
||||
|
||||
if(nthreads<=0) {
|
||||
errVerbose = errVerboseSave;
|
||||
return;
|
||||
}
|
||||
id = calloc(nthreads,sizeof(threadId));
|
||||
name = calloc(nthreads,sizeof(char *));
|
||||
arg = calloc(nthreads,sizeof(void *));
|
||||
pinfo = calloc(nthreads,sizeof(info *));
|
||||
stackSize = threadGetStackSize(threadStackSmall);
|
||||
for(i=0; i<nthreads; i++) {
|
||||
name[i] = calloc(10,sizeof(char));
|
||||
sprintf(name[i],"task%d",i);
|
||||
pinfo[i] = calloc(1,sizeof(info));
|
||||
pinfo[i]->threadnum = i;
|
||||
pinfo[i]->mutex = mutex;
|
||||
arg[i] = pinfo[i];
|
||||
id[i] = threadCreate(name[i],40,stackSize,mutexThread,arg[i]);
|
||||
printf("semTest created mutexThread %d id %p time %ld\n",
|
||||
i, id[i],time(&tp));
|
||||
}
|
||||
threadSleep(5.0);
|
||||
printf("semTest setting quit time %ld\n",time(&tp));
|
||||
for(i=0; i<nthreads; i++) {
|
||||
pinfo[i]->quit = 1;
|
||||
}
|
||||
threadSleep(2.0);
|
||||
errVerbose = errVerboseSave;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/* semMutexTestMain.c */
|
||||
|
||||
/* Author: Marty Kraimer Date: 26JAN2000 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "osiThread.h"
|
||||
void semMutexTest(int nthreads,int errVerbose);
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int nthreads = 2;
|
||||
int errVerbose = 0;
|
||||
|
||||
if(argc>1) {
|
||||
if(isdigit(*argv[1])) {
|
||||
sscanf(argv[1],"%d",&nthreads);
|
||||
printf("nthreads %d\n",nthreads);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
if(argc>2) {
|
||||
if(isdigit(*argv[2])) {
|
||||
sscanf(argv[2],"%d",&errVerbose);
|
||||
printf("errVerbose %d\n",errVerbose);
|
||||
} else {
|
||||
printf("Illegal argument %s\n",argv[1]);
|
||||
}
|
||||
}
|
||||
semMutexTest(nthreads,errVerbose);
|
||||
printf("main terminating\n");
|
||||
return(0);
|
||||
}
|
||||
Reference in New Issue
Block a user