new implementation of semBinary
This commit is contained in:
+118
-126
@@ -23,16 +23,13 @@ of this distribution.
|
||||
#include "tsStamp.h"
|
||||
#include "errlog.h"
|
||||
|
||||
|
||||
|
||||
typedef struct binary {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
}binary;
|
||||
|
||||
|
||||
typedef struct mutex {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_t mutexAttr;
|
||||
pthread_mutex_t lock; /*lock for structure */
|
||||
pthread_cond_t waitToBeOwner;
|
||||
int count;
|
||||
@@ -40,34 +37,44 @@ typedef struct mutex {
|
||||
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;
|
||||
|
||||
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(int initialState)
|
||||
{
|
||||
binary *pbinary;
|
||||
int status;
|
||||
|
||||
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");
|
||||
}
|
||||
#if defined _POSIX_THREAD_PRIO_PROTECT
|
||||
status = pthread_mutexattr_setprotocol(
|
||||
&pbinary->attr,PTHREAD_PROCESS_PRIVATE);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("semBinaryCreate pthread_mutexattr_setprotocal "
|
||||
"failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
#endif
|
||||
status = pthread_mutex_init(&pbinary->mutex,&pbinary->attr);
|
||||
if(status) {
|
||||
errlogPrintf("pthread_mutex_init failed: error %s\n",
|
||||
strerror(status));
|
||||
cantProceed("semBinaryCreate");
|
||||
}
|
||||
if(initialState==semEmpty) semBinaryTakeNoWait((semBinaryId)pbinary);
|
||||
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) semBinaryGive((semBinaryId)pbinary);
|
||||
return((semBinaryId)pbinary);
|
||||
}
|
||||
|
||||
@@ -84,65 +91,56 @@ void semBinaryDestroy(semBinaryId id)
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_destroy(&pbinary->mutex);
|
||||
if(status)
|
||||
errlogPrintf("pthread_mutex_destroy error %s\n",strerror(status));
|
||||
status = pthread_mutexattr_destroy(&pbinary->attr);
|
||||
if(status)
|
||||
errlogPrintf("pthread_mutexattr_destroy error %s\n", strerror(status));
|
||||
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_unlock(&pbinary->mutex);
|
||||
if(status)
|
||||
errlogPrintf("pthread_mutex_unlock error %s\n",strerror(status));
|
||||
status = pthread_cond_signal(&pbinary->cond);
|
||||
checkStatus(status,"pthread_cond_signal");
|
||||
}
|
||||
|
||||
|
||||
semTakeStatus semBinaryTake(semBinaryId id)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_lock(&pbinary->mutex);
|
||||
if(status) errlogPrintf("pthread_mutex_lock error %s\n",strerror(status));
|
||||
if(status) return(semTakeError);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semBinaryTake");
|
||||
status = pthread_cond_wait(&pbinary->cond,&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_cond_wait","semBinaryTake");
|
||||
status = pthread_mutex_unlock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_unlock","semBinaryTake");
|
||||
return(semTakeOK);
|
||||
}
|
||||
|
||||
semTakeStatus semBinaryTakeTimeout(semBinaryId id, double timeOut)
|
||||
semTakeStatus semBinaryTakeTimeout(semBinaryId id, double timeout)
|
||||
{
|
||||
binary *pbinary = (binary *)id;
|
||||
int status;
|
||||
double waitSoFar=0.0;
|
||||
struct timespec wakeTime;
|
||||
int status,unlockStatus;
|
||||
|
||||
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);
|
||||
convertDoubleToWakeTime(timeout,&wakeTime);
|
||||
status = pthread_mutex_lock(&pbinary->mutex);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semBinaryTakeTimeout");
|
||||
status = pthread_cond_timedwait(&pbinary->cond,&pbinary->mutex,&wakeTime);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return(semBinaryTakeTimeout(id,0.0));
|
||||
}
|
||||
|
||||
void semBinaryShow(semBinaryId id,unsigned int level)
|
||||
@@ -154,31 +152,17 @@ semMutexId semMutexCreate(void) {
|
||||
int status;
|
||||
|
||||
pmutex = callocMustSucceed(1,sizeof(mutex),"semMutexCreate");
|
||||
status = pthread_mutexattr_init(&pmutex->attr);
|
||||
if(status) {
|
||||
errlogPrintf("pthread_mutexattr_init failed: error %s\n",
|
||||
strerror(status));
|
||||
cantProceed("semMutexCreate");
|
||||
}
|
||||
status = pthread_mutexattr_init(&pmutex->mutexAttr);
|
||||
checkStatusQuit(status,"pthread_mutexattr_init","semMutexCreate");
|
||||
#ifdef _POSIX_THREAD_PRIO_INHERIT
|
||||
status = pthread_mutexattr_setprotocol(&pmutex->attr,PTHREAD_PRIO_INHERIT);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("pthread_mutexattr_setprotocal failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
status = pthread_mutexattr_setprotocol(
|
||||
&pmutex->mutexAttr,PTHREAD_PRIO_INHERIT);
|
||||
if(errVerbose) checkStatus(status,"pthread_mutexattr_setprotocal");
|
||||
#endif
|
||||
status = pthread_mutex_init(&pmutex->lock,&pmutex->attr);
|
||||
if(status) {
|
||||
errlogPrintf("pthread_mutex_init failed: error %s\n",
|
||||
strerror(status));
|
||||
cantProceed("semMutexCreate");
|
||||
}
|
||||
status = pthread_mutex_init(&pmutex->lock,&pmutex->mutexAttr);
|
||||
checkStatusQuit(status,"pthread_mutex_init","semMutexCreate");
|
||||
status = pthread_cond_init(&pmutex->waitToBeOwner,0);
|
||||
if(status) {
|
||||
errlogPrintf("pthread_cond_init failed: error %s\n",
|
||||
strerror(status));
|
||||
cantProceed("semMutexCreate");
|
||||
}
|
||||
checkStatusQuit(status,"pthread_cond_init","semMutexCreate");
|
||||
return((semMutexId)pmutex);
|
||||
}
|
||||
|
||||
@@ -195,76 +179,81 @@ void semMutexDestroy(semMutexId id)
|
||||
int status;
|
||||
|
||||
status = pthread_mutex_destroy(&pmutex->lock);
|
||||
if(status)
|
||||
errlogPrintf("pthread_mutex_destroy error %s\n",strerror(status));
|
||||
checkStatus(status,"pthread_mutex_destroy");
|
||||
status = pthread_cond_destroy(&pmutex->waitToBeOwner);
|
||||
if(status)
|
||||
errlogPrintf("pthread_cond_destroy error %s\n",strerror(status));
|
||||
status = pthread_mutexattr_destroy(&pmutex->attr);
|
||||
if(status)
|
||||
errlogPrintf("pthread_mutexattr_destroy error %s\n",strerror(status));
|
||||
checkStatus(status,"pthread_cond_destroy");
|
||||
status = pthread_mutexattr_destroy(&pmutex->mutexAttr);
|
||||
checkStatus(status,"pthread_mutexattr_destroy");
|
||||
free(pmutex);
|
||||
}
|
||||
|
||||
|
||||
void semMutexGive(semMutexId id)
|
||||
{
|
||||
mutex *pmutex = (mutex *)id;
|
||||
pthread_mutex_lock(&pmutex->lock);
|
||||
if(pmutex->count>0) pmutex->count--;
|
||||
int status,unlockStatus;
|
||||
|
||||
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);
|
||||
}
|
||||
pthread_mutex_unlock(&pmutex->lock);
|
||||
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;
|
||||
|
||||
pthread_mutex_lock(&pmutex->lock);
|
||||
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++;
|
||||
pthread_mutex_unlock(&pmutex->lock);
|
||||
return(0);
|
||||
}
|
||||
semTakeStatus semMutexTakeTimeout(semMutexId id, double timeOut)
|
||||
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 wait;
|
||||
struct timespec abstime;
|
||||
int status;
|
||||
TS_STAMP stamp;
|
||||
struct timespec wakeTime;
|
||||
int status,unlockStatus;
|
||||
|
||||
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);
|
||||
convertDoubleToWakeTime(timeout,&wakeTime);
|
||||
status = pthread_mutex_lock(&pmutex->lock);
|
||||
checkStatusQuit(status,"pthread_mutex_lock","semMutexTakeTimeout");
|
||||
while(pmutex->owned && !pthread_equal(pmutex->ownerTid,tid)) {
|
||||
int status;
|
||||
status = pthread_cond_timedwait(
|
||||
&pmutex->waitToBeOwner,&pmutex->lock,&abstime);
|
||||
&pmutex->waitToBeOwner,&pmutex->lock,&wakeTime);
|
||||
if(!status) break;
|
||||
if(status==ETIMEDOUT) return(semTakeTimeout);
|
||||
return(semTakeError);
|
||||
}
|
||||
pmutex->ownerTid = tid;
|
||||
pmutex->owned = 1;
|
||||
pmutex->count++;
|
||||
pthread_mutex_unlock(&pmutex->lock);
|
||||
return(0);
|
||||
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)
|
||||
@@ -272,15 +261,18 @@ semTakeStatus semMutexTakeNoWait(semMutexId id)
|
||||
mutex *pmutex = (mutex *)id;
|
||||
pthread_t tid = pthread_self();
|
||||
semTakeStatus status = semTakeError;
|
||||
int pthreadStatus;
|
||||
|
||||
pthread_mutex_lock(&pmutex->lock);
|
||||
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;
|
||||
}
|
||||
pthread_mutex_unlock(&pmutex->lock);
|
||||
pthreadStatus = pthread_mutex_unlock(&pmutex->lock);
|
||||
checkStatusQuit(pthreadStatus,"pthread_mutex_unlock","semMutexTakeNoWait");
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,16 @@ typedef struct threadInfo {
|
||||
static pthread_key_t getpthreadInfo;
|
||||
static commonAttr *pcommonAttr = 0;
|
||||
|
||||
#define checkStatus(status,message) \
|
||||
if((status)) {\
|
||||
errlogPrintf("%s error %s\n",(message),strerror((status))); }
|
||||
|
||||
#define checkStatusQuit(status,message,method) \
|
||||
if(status) { \
|
||||
errlogPrintf("%s error %s\n",(message),strerror((status))); \
|
||||
cantProceed((method)); \
|
||||
}
|
||||
|
||||
static void once(void)
|
||||
{
|
||||
int status;
|
||||
@@ -55,34 +65,19 @@ static void once(void)
|
||||
pthread_key_create(&getpthreadInfo,0);
|
||||
pcommonAttr = callocMustSucceed(1,sizeof(commonAttr),"osdThread:once");
|
||||
status = pthread_attr_init(&pcommonAttr->attr);
|
||||
if(status) {
|
||||
printf("pthread_attr_init failed: error %s\n",strerror(status));
|
||||
cantProceed("threadCreate::once");
|
||||
}
|
||||
checkStatusQuit(status,"pthread_attr_init","threadCreate::once");
|
||||
status = pthread_attr_setdetachstate(
|
||||
&pcommonAttr->attr, PTHREAD_CREATE_DETACHED);
|
||||
if(status) {
|
||||
printf("pthread_attr_setdetachstate1 failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
checkStatus(status,"pthread_attr_setdetachstate");
|
||||
status = pthread_attr_setscope(&pcommonAttr->attr,PTHREAD_SCOPE_PROCESS);
|
||||
if(status) {
|
||||
printf("pthread_attr_setscope failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setscope");
|
||||
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
|
||||
status = pthread_attr_getschedpolicy(
|
||||
&pcommonAttr->attr,&pcommonAttr->schedPolicy);
|
||||
if(status) {
|
||||
printf("pthread_attr_getschedparam failed %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
checkStatus(status,"pthread_attr_getschedpolicy");
|
||||
status = pthread_attr_getschedparam(
|
||||
&pcommonAttr->attr,&pcommonAttr->schedParam);
|
||||
if(status) {
|
||||
printf("pthread_attr_getschedparam failed %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
checkStatus(status,"pthread_attr_getschedparam");
|
||||
pcommonAttr->maxPriority = sched_get_priority_max(pcommonAttr->schedPolicy);
|
||||
if(pcommonAttr->maxPriority == -1) {
|
||||
pcommonAttr->maxPriority = pcommonAttr->schedParam.sched_priority;
|
||||
@@ -96,17 +91,20 @@ static void once(void)
|
||||
pcommonAttr->maxPriority);
|
||||
}
|
||||
#else
|
||||
printf("task priorities are not implemented\n");
|
||||
if(errVerbose) printf("task priorities are not implemented\n");
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
}
|
||||
|
||||
static void * start_routine(void *arg)
|
||||
{
|
||||
threadInfo *pthreadInfo = (threadInfo *)arg;
|
||||
pthread_setspecific(getpthreadInfo,arg);
|
||||
int status;
|
||||
status = pthread_setspecific(getpthreadInfo,arg);
|
||||
checkStatusQuit(status,"pthread_setspecific","start_routine");
|
||||
(*pthreadInfo->createFunc)(pthreadInfo->createArg);
|
||||
semBinaryDestroy(pthreadInfo->suspendSem);
|
||||
pthread_attr_destroy(&pthreadInfo->attr);
|
||||
status = pthread_attr_destroy(&pthreadInfo->attr);
|
||||
checkStatusQuit(status,"pthread_attr_destroy","start_routine");
|
||||
free(pthreadInfo);
|
||||
return(0);
|
||||
}
|
||||
@@ -167,37 +165,22 @@ threadId threadCreate(const char *name,
|
||||
pthreadInfo->createFunc = funptr;
|
||||
pthreadInfo->createArg = parm;
|
||||
status = pthread_attr_init(&pthreadInfo->attr);
|
||||
if(status) {
|
||||
errlogPrintf("pthread_attr_init failed: error %s\n",strerror(status));
|
||||
cantProceed("threadCreate");
|
||||
}
|
||||
checkStatusQuit(status,"pthread_attr_init","threadCreate");
|
||||
status = pthread_attr_setdetachstate(
|
||||
&pthreadInfo->attr, PTHREAD_CREATE_DETACHED);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("pthread_attr_setdetachstate1 failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setdetachstate");
|
||||
#if defined (_POSIX_THREAD_ATTR_STACKSIZE)
|
||||
status = pthread_attr_setstacksize(
|
||||
&pthreadInfo->attr, (size_t)stackSize);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("pthread_attr_setstacksize failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setstacksize");
|
||||
#endif
|
||||
status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("pthread_attr_setscope failed: error %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setscope");
|
||||
pthreadInfo->osiPriority = priority;
|
||||
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING)
|
||||
status = pthread_attr_getschedparam(
|
||||
&pthreadInfo->attr,&pthreadInfo->schedParam);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("pthread_attr_getschedparam failed %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_getschedparam");
|
||||
pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo);
|
||||
status = pthread_attr_setschedparam(
|
||||
&pthreadInfo->attr,&pthreadInfo->schedParam);
|
||||
@@ -209,18 +192,12 @@ threadId threadCreate(const char *name,
|
||||
}
|
||||
status = pthread_attr_setinheritsched(
|
||||
&pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("threadCreate: pthread_attr_setinheritsched failed %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setinheritsched");
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
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");
|
||||
}
|
||||
checkStatusQuit(status,"pthread_create","threadCreate");
|
||||
return((threadId)pthreadInfo);
|
||||
}
|
||||
|
||||
@@ -256,16 +233,10 @@ void threadSetPriority(threadId id,unsigned int priority)
|
||||
pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo);
|
||||
status = pthread_attr_setschedparam(
|
||||
&pthreadInfo->attr,&pthreadInfo->schedParam);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("threadSetPriority: pthread_attr_setschedparam "
|
||||
"failed %s\n", strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_attr_setschedparam");
|
||||
status = pthread_setschedparam(
|
||||
pthreadInfo->tid,pcommonAttr->schedPolicy,&pthreadInfo->schedParam);
|
||||
if(status && errVerbose) {
|
||||
errlogPrintf("threadSetPriority: pthread_setschedparam failed %s\n",
|
||||
strerror(status));
|
||||
}
|
||||
if(errVerbose) checkStatus(status,"pthread_setschedparam");
|
||||
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
|
||||
}
|
||||
|
||||
@@ -289,9 +260,11 @@ void threadSleep(double seconds)
|
||||
{
|
||||
struct timespec delayTime;
|
||||
struct timespec remainingTime;
|
||||
double nanoseconds;
|
||||
|
||||
delayTime.tv_sec = (time_t)seconds;
|
||||
delayTime.tv_nsec = (long)(seconds - (double)delayTime.tv_sec);
|
||||
nanoseconds = (seconds - (double)delayTime.tv_sec) *1e9;
|
||||
delayTime.tv_nsec = (long)nanoseconds;
|
||||
nanosleep(&delayTime,&remainingTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,25 +31,24 @@ static void mutexThread(void *arg)
|
||||
{
|
||||
info *pinfo = (info *)arg;
|
||||
time_t tp;
|
||||
printf("mutexThread %d starting time %d\n",pinfo->threadnum,time(&tp));
|
||||
threadSleep(1.0);
|
||||
printf("mutexThread %d starting time %ld\n",pinfo->threadnum,time(&tp));
|
||||
while(1) {
|
||||
semTakeStatus status;
|
||||
if(pinfo->quit) {
|
||||
printf("mutexThread %d returning time %d\n",
|
||||
printf("mutexThread %d returning time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
semMutexGive(pinfo->mutex);
|
||||
return;
|
||||
}
|
||||
status = semMutexTake(pinfo->mutex);
|
||||
if(status!=semTakeOK) {
|
||||
printf("task %d semMutexTake returned %d time %d\n",
|
||||
printf("task %d semMutexTake returned %d time %ld\n",
|
||||
pinfo->threadnum,(int)status,time(&tp));
|
||||
}
|
||||
printf("mutexThread %d semMutexTake time %d\n",
|
||||
printf("mutexThread %d semMutexTake time %ld\n",
|
||||
pinfo->threadnum,time(&tp));
|
||||
threadSleep(.1);
|
||||
semMutexGive(pinfo->mutex);
|
||||
threadSleep(1.0);
|
||||
threadSleep(.9);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,21 +67,21 @@ void semMutexTest(int nthreads,int verbose)
|
||||
|
||||
errVerbose = verbose;
|
||||
mutex = semMutexMustCreate();
|
||||
printf("calling semMutexTake(mutex) time %d\n",time(&tp));
|
||||
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 %d\n",time(&tp));
|
||||
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 %d\n",time(&tp));
|
||||
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 %d\n",time(&tp));
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
printf("calling semMutexGive() time %d\n",time(&tp));
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
printf("calling semMutexGive() time %d\n",time(&tp));
|
||||
printf("calling semMutexGive() time %ld\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
semMutexShow(mutex,1);
|
||||
|
||||
@@ -103,18 +102,14 @@ void semMutexTest(int nthreads,int verbose)
|
||||
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 %d\n",
|
||||
printf("semTest created mutexThread %d id %p time %ld\n",
|
||||
i, id[i],time(&tp));
|
||||
}
|
||||
threadSleep(2.0);
|
||||
printf("semTest calling semMutexGive(mutex) time %d\n",time(&tp));
|
||||
semMutexGive(mutex);
|
||||
threadSleep(5.0);
|
||||
printf("semTest setting quit time %d\n",time(&tp));
|
||||
printf("semTest setting quit time %ld\n",time(&tp));
|
||||
for(i=0; i<nthreads; i++) {
|
||||
pinfo[i]->quit = 1;
|
||||
}
|
||||
semMutexGive(mutex);
|
||||
threadSleep(2.0);
|
||||
errVerbose = errVerboseSave;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ of this distribution.
|
||||
static void threadFunc(void *arg)
|
||||
{
|
||||
int argvalue = *(int *)arg;
|
||||
errlogPrintf("threadFunc %d starting\n",argvalue);
|
||||
printf("threadFunc %d starting\n",argvalue);
|
||||
threadSleep(2.0);
|
||||
errlogPrintf("threadFunc %d stopping\n",argvalue);
|
||||
printf("threadFunc %d stopping\n",argvalue);
|
||||
}
|
||||
|
||||
void threadTest(int ntasks,int verbose)
|
||||
@@ -39,13 +39,14 @@ void threadTest(int ntasks,int verbose)
|
||||
int startPriority,minPriority,maxPriority;
|
||||
int errVerboseSave = errVerbose;
|
||||
|
||||
printf("threadTest ntasks %d verbose %d\n",ntasks,verbose);
|
||||
errVerbose = verbose;
|
||||
id = calloc(ntasks,sizeof(threadId *));
|
||||
name = calloc(ntasks,sizeof(char **));
|
||||
arg = calloc(ntasks,sizeof(void *));
|
||||
errlogPrintf("threadTest starting\n");
|
||||
printf("threadTest starting\n");
|
||||
stackSize = threadGetStackSize(threadStackSmall);
|
||||
errlogPrintf("stackSize %u\n",stackSize);
|
||||
printf("stackSize %u\n",stackSize);
|
||||
for(i=0; i<ntasks; i++) {
|
||||
int *argvalue;
|
||||
name[i] = calloc(10,sizeof(char));
|
||||
@@ -55,18 +56,18 @@ void threadTest(int ntasks,int verbose)
|
||||
*argvalue = i;
|
||||
startPriority = 50+i;
|
||||
id[i] = threadCreate(name[i],startPriority,stackSize,threadFunc,arg[i]);
|
||||
errlogPrintf("threadTest created %d id %p\n",i,id[i]);
|
||||
printf("threadTest created %d id %p\n",i,id[i]);
|
||||
startPriority = threadGetPriority(id[i]);
|
||||
threadSetPriority(id[i],threadPriorityMin);
|
||||
minPriority = threadGetPriority(id[i]);
|
||||
threadSetPriority(id[i],threadPriorityMax);
|
||||
maxPriority = threadGetPriority(id[i]);
|
||||
threadSetPriority(id[i],50+i);
|
||||
if(i==0)errlogPrintf("startPriority %d minPriority %d maxPriority %d\n",
|
||||
if(i==0)printf("startPriority %d minPriority %d maxPriority %d\n",
|
||||
startPriority,minPriority,maxPriority);
|
||||
}
|
||||
|
||||
threadSleep(5.0);
|
||||
errlogPrintf("threadTest terminating\n");
|
||||
printf("threadTest terminating\n");
|
||||
errVerbose = errVerboseSave;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user