replace osiSem by epicsMutex/epiceEvent

This commit is contained in:
Marty Kraimer
2001-01-12 16:13:53 +00:00
parent 1ecd0c520c
commit cfe2ed5f17
24 changed files with 138 additions and 2042 deletions

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -1,9 +0,0 @@
/*
* RTEMS osdSem.h
* $Id$
* Author: W. Eric Norum
* eric@cls.usask.ca
* (306) 966-6055
*/
/* osdSem.h not needed */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);}

View File

@@ -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);
}

View File

@@ -1 +0,0 @@
/* for a pure posix implementation no osdSem.h definitions are needed*/

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}