latest version of osiSem and osiThread

This commit is contained in:
Marty Kraimer
2000-01-28 15:06:47 +00:00
parent 35051088fd
commit e517f56be5
3 changed files with 140 additions and 89 deletions

View File

@@ -18,14 +18,17 @@ of this distribution.
#include <pthread.h>
#include "osiSem.h"
#include "osiThread.h"
#include "cantProceed.h"
#include "tsStamp.h"
#include "errlog.h"
typedef struct cond {
typedef struct binary {
pthread_mutexattr_t attr;
pthread_mutex_t mutex;
pthread_cond_t condition;
}cond;
}binary;
typedef struct mutex {
@@ -36,87 +39,113 @@ typedef struct mutex {
int owned; /* TRUE | FALSE */
pthread_t ownerTid;
}mutex;
semId semBinaryCreate(int initialState)
semBinaryId semBinaryCreate(int initialState)
{
cond *pcond;
binary *pbinary;
int status;
pcond = callocMustSucceed(1,sizeof(cond),"semBinaryCreate");
status = pthread_mutex_init(&pcond->mutex,0);
pbinary = callocMustSucceed(1,sizeof(binary),"semBinaryCreate");
status = pthread_mutexattr_init(&pbinary->attr);
if(status) {
errlogPrintf("pthread_mutexattr_init failed: error %s\n",
strerror(status));
cantProceed("semBinaryCreate");
}
status = pthread_mutexattr_setprotocol(
&pbinary->attr,PTHREAD_PROCESS_PRIVATE);
/* For now dont report failure
if(status) {
errlogPrintf("semBinaryCreate pthread_mutexattr_setprotocal "
"failed: error %s\n",
strerror(status));
}
*/
status = pthread_mutex_init(&pbinary->mutex,&pbinary->attr);
if(status) {
errlogPrintf("pthread_mutex_init failed: error %s\n",
strerror(status));
}
status = pthread_mutex_init(&pbinary->mutex,&pbinary->attr);
if(status) {
errlogPrintf("pthread_mutex_init failed: error %s\n",
strerror(status));
cantProceed("semBinaryCreate");
}
status = pthread_cond_init(&pcond->condition,0);
if(status) {
errlogPrintf("pthread_cond_init failed: error %s\n",
strerror(status));
cantProceed("semBinaryCreate");
}
return((semId)pcond);
if(initialState==semEmpty) semBinaryTakeNoWait((semBinaryId)pbinary);
return((semBinaryId)pbinary);
}
void semBinaryDestroy(semId id)
void semBinaryDestroy(semBinaryId id)
{
cond *pcond = (cond *)id;
binary *pbinary = (binary *)id;
int status;
status = pthread_mutex_destroy(&pcond->mutex);
status = pthread_mutex_destroy(&pbinary->mutex);
if(status) errlogPrintf("pthread_mutex_destroy error %s\n",strerror(status));
status = pthread_cond_destroy(&pcond->condition);
if(status) errlogPrintf("pthread_cond_destroy error %s\n",strerror(status));
free(pcond);
status = pthread_mutexattr_destroy(&pbinary->attr);
if(status) errlogPrintf("pthread_mutexattr_destroy error %s\n",
strerror(status));
free(pbinary);
}
void semBinaryGive(semId id)
void semBinaryGive(semBinaryId id)
{
cond *pcond = (cond *)id;
binary *pbinary = (binary *)id;
int status;
status = pthread_cond_signal(&pcond->condition);
if(status) errlogPrintf("pthread_cond_signal error %s\n",strerror(status));
status = pthread_mutex_unlock(&pbinary->mutex);
if(status) errlogPrintf("pthread_mutex_unlock error %s\n",strerror(status));
}
semTakeStatus semBinaryTake(semId id)
semTakeStatus semBinaryTake(semBinaryId id)
{
cond *pcond = (cond *)id;
binary *pbinary = (binary *)id;
int status;
status = pthread_cond_wait(&pcond->condition,&pcond->mutex);
if(status) errlogPrintf("pthread_cond_wait error %s\n",strerror(status));
status = pthread_mutex_lock(&pbinary->mutex);
if(status) errlogPrintf("pthread_mutex_lock error %s\n",strerror(status));
if(status) return(semTakeError);
return(semTakeOK);
}
semTakeStatus semBinaryTakeTimeout(semId id, double timeOut)
semTakeStatus semBinaryTakeTimeout(semBinaryId id, double timeOut)
{
cond *pcond = (cond *)id;
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
struct timespec wait;
int status;
binary *pbinary = (binary *)id;
int status;
double waitSoFar=0.0;
wait.tv_sec = timeOut;
wait.tv_nsec = (long)((timeOut - (double)wait.tv_sec) * 1e9);
status = pthread_cond_timedwait(
&pcond->condition,&pcond->mutex,&wait);
if(status==ETIMEDOUT) return(semTakeTimeout);
if(status) errlogPrintf("pthread_cond_wait error %s\n",strerror(status));
return(0);
while(1) {
status = pthread_mutex_trylock(&pbinary->mutex);
if(!status) return(semTakeOK);
if(status!=EBUSY) {
errlogPrintf("pthread_mutex_lock error %s\n",strerror(status));
return(semTakeError);
}
threadSleep(1.0);
waitSoFar += 1.0;
if(waitSoFar>=timeOut) break;
}
return(semTakeTimeout);
}
semTakeStatus semBinaryTakeNoWait(semId id)
semTakeStatus semBinaryTakeNoWait(semBinaryId id)
{
return(semBinaryTakeTimeout(id,0.0));
binary *pbinary = (binary *)id;
int status;
status = pthread_mutex_trylock(&pbinary->mutex);
if(!status) return(semTakeOK);
if(status==EBUSY) return(semTakeTimeout);
errlogPrintf("pthread_mutex_lock error %s\n",strerror(status));
return(semTakeError);
}
void semBinaryShow(semId id)
void semBinaryShow(semBinaryId id)
{
}
semId semMutexCreate(void) {
semMutexId semMutexCreate(void) {
mutex *pmutex;
int status;
@@ -146,10 +175,10 @@ semId semMutexCreate(void) {
strerror(status));
cantProceed("semMutexCreate");
}
return((semId)pmutex);
return((semMutexId)pmutex);
}
void semMutexDestroy(semId id)
void semMutexDestroy(semMutexId id)
{
mutex *pmutex = (mutex *)id;
int status;
@@ -162,12 +191,12 @@ void semMutexDestroy(semId id)
if(status) errlogPrintf("pthread_mutexattr_destroy error %s\n",strerror(status));
free(pmutex);
}
void semMutexGive(semId id)
void semMutexGive(semMutexId id)
{
mutex *pmutex = (mutex *)id;
pthread_mutex_lock(&pmutex->lock);
pmutex->count--;
if(pmutex->count>0) pmutex->count--;
if(pmutex->count == 0) {
pmutex->owned = 0;
pmutex->ownerTid = 0;
@@ -175,7 +204,7 @@ void semMutexGive(semId id)
}
pthread_mutex_unlock(&pmutex->lock);
}
semTakeStatus semMutexTake(semId id)
semTakeStatus semMutexTake(semMutexId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
@@ -188,21 +217,31 @@ semTakeStatus semMutexTake(semId id)
pmutex->count++;
pthread_mutex_unlock(&pmutex->lock);
return(0);
}
semTakeStatus semMutexTakeTimeout(semId id, double timeOut)
}
semTakeStatus semMutexTakeTimeout(semMutexId id, double timeOut)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
struct timespec wait;
struct timespec abstime;
int status;
TS_STAMP stamp;
tsStampGetCurrent(&stamp);
tsStampToTimespec(&abstime, &stamp);
wait.tv_sec = timeOut;
wait.tv_nsec = (long)((timeOut - (double)wait.tv_sec) * 1e9);
abstime.tv_sec += wait.tv_sec;
abstime.tv_nsec += wait.tv_nsec;
if(abstime.tv_nsec>1000000000L) {
abstime.tv_nsec -= 1000000000L;
++abstime.tv_sec;
}
pthread_mutex_lock(&pmutex->lock);
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) {
int status;
status = pthread_cond_timedwait(
&pmutex->waitToBeOwner,&pmutex->lock,&wait);
&pmutex->waitToBeOwner,&pmutex->lock,&abstime);
if(!status) break;
if(status==ETIMEDOUT) return(semTakeTimeout);
return(semTakeError);
@@ -213,7 +252,8 @@ semTakeStatus semMutexTakeTimeout(semId id, double timeOut)
pthread_mutex_unlock(&pmutex->lock);
return(0);
}
semTakeStatus semMutexTakeNoWait(semId id)
semTakeStatus semMutexTakeNoWait(semMutexId id)
{
mutex *pmutex = (mutex *)id;
pthread_t tid = pthread_self();
@@ -229,7 +269,8 @@ semTakeStatus semMutexTakeNoWait(semId id)
pthread_mutex_unlock(&pmutex->lock);
return(status);
}
void semMutexShow(semId id)
void semMutexShow(semMutexId id)
{
mutex *pmutex = (mutex *)id;
printf("ownerTid %p count %d owned %d\n",

View File

@@ -33,7 +33,7 @@ typedef struct threadInfo {
struct sched_param schedParam;
THREADFUNC createFunc;
void *createArg;
semId suspendSem;
semBinaryId suspendSem;
int isSuspended;
int maxPriority;
int minPriority;
@@ -109,6 +109,8 @@ threadId threadCreate(const char *name,
pthread_key_create(&getpthreadInfo,0);
}
pthreadInfo = callocMustSucceed(1,sizeof(threadInfo),"threadCreate");
pthreadInfo->createFunc = funptr;
pthreadInfo->createArg = parm;
status = pthread_attr_init(&pthreadInfo->attr);
if(status) {
errlogPrintf("pthread_attr_init failed: error %s\n",strerror(status));
@@ -126,8 +128,11 @@ threadId threadCreate(const char *name,
errlogPrintf("pthread_attr_setstacksize failed: error %s\n",
strerror(status));
}
/* DO WE WANT TO setscope ???? */
/*pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_SYSTEM);*/
status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS);
if(status) {
errlogPrintf("pthread_attr_setscope failed: error %s\n",
strerror(status));
}
pthreadInfo->schedPolicy = SCHED_FIFO;
pthreadInfo->maxPriority = sched_get_priority_max(pthreadInfo->schedPolicy);
pthreadInfo->minPriority = sched_get_priority_min(pthreadInfo->schedPolicy);
@@ -137,7 +142,6 @@ threadId threadCreate(const char *name,
if(status) {
errlogPrintf("pthread_attr_setschedpolicy failed: error %s\n",
strerror(status));
cantProceed("threadCreate");
}
pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo);
status = pthread_attr_setschedparam(
@@ -145,14 +149,15 @@ threadId threadCreate(const char *name,
if(status) {
errlogPrintf("pthread_attr_setschedparam failed: error %s\n",
strerror(status));
cantProceed("threadCreate");
}
pthreadInfo->suspendSem = semBinaryMustCreate(semFull);
status = pthread_create(&pthreadInfo->tid,
&pthreadInfo->attr,start_routine,pthreadInfo);
if(status) {
errlogPrintf("pthread_create failed: error %s\n",strerror(status));
/*
cantProceed("threadCreate");
*/
}
return((threadId)pthreadInfo);
}

View File

@@ -9,55 +9,60 @@ extern "C" {
#include "shareLib.h"
typedef void *semId;
typedef void *semBinaryId;
typedef enum {semTakeOK,semTakeTimeout,semTakeError} semTakeStatus;
typedef enum {semEmpty,semFull} semInitialState;
epicsShareFunc semId epicsShareAPI semBinaryCreate(int initialState);
epicsShareFunc INLINE semId epicsShareAPI semBinaryMustCreate (int initialState);
epicsShareFunc void epicsShareAPI semBinaryDestroy(semId id);
epicsShareFunc void epicsShareAPI semBinaryGive(semId id);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTake(semId id);
epicsShareFunc INLINE void epicsShareAPI semBinaryMustTake (semId id);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeTimeout(semId id, double timeOut);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeNoWait(semId id);
epicsShareFunc void epicsShareAPI semBinaryShow(semId id);
epicsShareFunc semBinaryId epicsShareAPI semBinaryCreate(int initialState);
epicsShareFunc INLINE semBinaryId epicsShareAPI semBinaryMustCreate (
int initialState);
epicsShareFunc void epicsShareAPI semBinaryDestroy(semBinaryId id);
epicsShareFunc void epicsShareAPI semBinaryGive(semBinaryId id);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTake(semBinaryId id);
epicsShareFunc INLINE void epicsShareAPI semBinaryMustTake (semBinaryId id);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeTimeout(
semBinaryId id, double timeOut);
epicsShareFunc semTakeStatus epicsShareAPI semBinaryTakeNoWait(semBinaryId id);
epicsShareFunc void epicsShareAPI semBinaryShow(semBinaryId id);
epicsShareFunc semId epicsShareAPI semMutexCreate(void);
epicsShareFunc INLINE semId epicsShareAPI semMutexMustCreate (void);
epicsShareFunc void epicsShareAPI semMutexDestroy(semId id);
epicsShareFunc void epicsShareAPI semMutexGive(semId id);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake(semId id);
epicsShareFunc INLINE void epicsShareAPI semMutexMustTake(semId id);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout(semId id, double timeOut);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait(semId id);
epicsShareFunc void epicsShareAPI semMutexShow(semId id);
typedef void *semMutexId;
epicsShareFunc semMutexId epicsShareAPI semMutexCreate(void);
epicsShareFunc INLINE semMutexId epicsShareAPI semMutexMustCreate (void);
epicsShareFunc void epicsShareAPI semMutexDestroy(semMutexId id);
epicsShareFunc void epicsShareAPI semMutexGive(semMutexId id);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTake(semMutexId id);
epicsShareFunc INLINE void epicsShareAPI semMutexMustTake(semMutexId id);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeTimeout(
semMutexId id, double timeOut);
epicsShareFunc semTakeStatus epicsShareAPI semMutexTakeNoWait(semMutexId id);
epicsShareFunc void epicsShareAPI semMutexShow(semMutexId id);
/*NOTES:
Mutex semaphores MUST implement recursive locking
Mutex semaphores should implement priority inheritance and deletion safe
*/
epicsShareFunc INLINE semId epicsShareAPI semBinaryMustCreate (int initialState)
epicsShareFunc INLINE semBinaryId epicsShareAPI semBinaryMustCreate (
int initialState)
{
semId id = semBinaryCreate (initialState);
semBinaryId id = semBinaryCreate (initialState);
assert (id);
return id;
}
epicsShareFunc INLINE void epicsShareAPI semBinaryMustTake (semId id)
epicsShareFunc INLINE void epicsShareAPI semBinaryMustTake (semBinaryId id)
{
assert (semBinaryTake (id)==semTakeOK);
}
epicsShareFunc INLINE semId epicsShareAPI semMutexMustCreate (void)
epicsShareFunc INLINE semMutexId epicsShareAPI semMutexMustCreate (void)
{
semId id = semMutexCreate ();
semMutexId id = semMutexCreate ();
assert (id);
return id;
}
epicsShareFunc INLINE void epicsShareAPI semMutexMustTake(semId id)
epicsShareFunc INLINE void epicsShareAPI semMutexMustTake(semMutexId id)
{
assert (semMutexTake (id)==semTakeOK);
}