コード例 #1
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexOSD * epicsMutexOsdCreate(void) {
    epicsMutexOSD *pmutex;
    int           status;

    pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
    status = pthread_mutexattr_init(&pmutex->mutexAttr);
    checkStatusQuit(status, "pthread_mutexattr_init", "epicsMutexOsdCreate");

#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", "epicsMutexOsdCreate");

#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", "epicsMutexOsdCreate");
    return pmutex;
}
コード例 #2
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsigned int level)
{
    epicsThreadOSD *pthreadInfo;
    int status;
    int found = 0;

    epicsThreadInit();
    if(!showThread) {
        showThreadInfo(0,level);
        return;
    }
    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll");
    pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
    while(pthreadInfo) {
        if (((epicsThreadId)pthreadInfo == showThread)
         || ((epicsThreadId)pthreadInfo->tid == showThread)) {
            found = 1;
            showThreadInfo(pthreadInfo,level);
        }
        pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
    }
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll");
    if (!found)
        printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread);
}
コード例 #3
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
static void * start_routine(void *arg)
{
    epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg;
    int status;
    int oldtype;
    sigset_t blockAllSig;
 
    sigfillset(&blockAllSig);
    pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL);
    status = pthread_setspecific(getpthreadInfo,arg);
    checkStatusQuit(status,"pthread_setspecific","start_routine");
    status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype);
    checkStatusQuit(status,"pthread_setcanceltype","start_routine");
    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","start_routine");
    ellAdd(&pthreadList,&pthreadInfo->node);
    pthreadInfo->isOnThreadList = 1;
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","start_routine");

    (*pthreadInfo->createFunc)(pthreadInfo->createArg);

    epicsExitCallAtThreadExits ();

    free_threadInfo(pthreadInfo);
    return(0);
}
コード例 #4
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
static void free_threadInfo(epicsThreadOSD *pthreadInfo)
{
    int status;

    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo");
    if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node);
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo");
    epicsEventDestroy(pthreadInfo->suspendEvent);
    status = pthread_attr_destroy(&pthreadInfo->attr);
    checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo");
    free(pthreadInfo->name);
    free(pthreadInfo);
}
コード例 #5
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
{
    int status;

    status = pthread_mutex_unlock(&pmutex->lock);
    checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
}
コード例 #6
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
/*
 * Create dummy context for threads not created by epicsThreadCreate().
 */
static epicsThreadOSD *createImplicit(void)
{
    epicsThreadOSD *pthreadInfo;
    char name[64];
    pthread_t tid;
    int status;

    tid = pthread_self();
    sprintf(name, "non-EPICS_%ld", (long)tid);
    pthreadInfo = create_threadInfo(name);
    pthreadInfo->tid = tid;
    pthreadInfo->osiPriority = 0;
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) 
    {
    struct sched_param param;
    int policy;
    if(pthread_getschedparam(tid,&policy,&param) == 0)
        pthreadInfo->osiPriority =
                 (param.sched_priority - pcommonAttr->minPriority) * 100.0 /
                    (pcommonAttr->maxPriority - pcommonAttr->minPriority + 1);
    }
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
    checkStatusQuit(status,"pthread_setspecific","createImplicit");
/*    pthread_cleanup_push(nonEPICSthreadCleanup, pthreadInfo); */
    return pthreadInfo;
}
コード例 #7
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level)
{
    epicsThreadOSD *pthreadInfo;
    int status;

    epicsThreadInit();
    epicsThreadShow(0,level);
    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll");
    pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
    while(pthreadInfo) {
        showThreadInfo(pthreadInfo,level);
        pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
    }
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll");
}
コード例 #8
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name) {
    epicsThreadOSD *pthreadInfo;
    int status;

    assert(epicsThreadOnceCalled);
    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","epicsThreadGetId");
    pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList);
    while(pthreadInfo) {
    if(strcmp(name,pthreadInfo->name) == 0) break;
        pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node);
    }
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadGetId");

    return(pthreadInfo);
}
コード例 #9
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id)
{
    pthread_key_t *key = (pthread_key_t *)id;
    int status;

    assert(epicsThreadOnceCalled);
    status = pthread_key_delete(*key);
    checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete");
    free((void *)key);
}
コード例 #10
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
{
    int status;

    if (!pmutex) return epicsMutexLockError;
    status = mutexLock(&pmutex->lock);
    if (status == EINVAL) return epicsMutexLockError;
    checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");
    return epicsMutexLockOK;
}
コード例 #11
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc void epicsShareAPI epicsThreadPrivateSet (epicsThreadPrivateId id, void *value)
{
    pthread_key_t *key = (pthread_key_t *)id;
    int status;

    assert(epicsThreadOnceCalled);
    if(errVerbose && !value)
        errlogPrintf("epicsThreadPrivateSet: setting value of 0\n");
    status = pthread_setspecific(*key,value);
    checkStatusQuit(status,"pthread_setspecific","epicsThreadPrivateSet");
}
コード例 #12
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void)
{
    pthread_key_t *key;
    int status;

    epicsThreadInit();
    key = callocMustSucceed(1,sizeof(pthread_key_t),"epicsThreadPrivateCreate");
    status = pthread_key_create(key,0);
    checkStatusQuit(status,"pthread_key_create","epicsThreadPrivateCreate");
    return((epicsThreadPrivateId)key);
}
コード例 #13
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
{
    int status;

    if (!pmutex) return epicsMutexLockError;
    status = pthread_mutex_trylock(&pmutex->lock);
    if (status == EINVAL) return epicsMutexLockError;
    if (status == EBUSY) return epicsMutexLockTimeout;
    checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");
    return epicsMutexLockOK;
}
コード例 #14
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex)
{
    pthread_t tid = pthread_self();
    int status;

    if (!pmutex || !tid) return epicsMutexLockError;
    status = mutexLock(&pmutex->lock);
    if (status == EINVAL) return epicsMutexLockError;
    checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdLock");

    while (pmutex->owned && !pthread_equal(pmutex->ownerTid, tid))
        condWait(&pmutex->waitToBeOwner, &pmutex->lock);
    pmutex->ownerTid = tid;
    pmutex->owned = 1;
    pmutex->count++;

    status = pthread_mutex_unlock(&pmutex->lock);
    checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdLock");
    return epicsMutexLockOK;
}
コード例 #15
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexOSD * epicsMutexOsdCreate(void) {
    epicsMutexOSD *pmutex;
    int status;

    pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
    status = pthread_mutexattr_init(&pmutex->mutexAttr);
    checkStatusQuit(status,"pthread_mutexattr_init", "epicsMutexOsdCreate");

#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_mutexattr_settype(&pmutex->mutexAttr,
        PTHREAD_MUTEX_RECURSIVE);
    if (errVerbose) checkStatus(status, "pthread_mutexattr_settype");

    status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
    checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
    return pmutex;
}
コード例 #16
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex)
{
    pthread_t tid = pthread_self();
    epicsMutexLockStatus result;
    int status;

    status = mutexLock(&pmutex->lock);
    if (status == EINVAL) return epicsMutexLockError;
    checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdTryLock");

    if (!pmutex->owned || pthread_equal(pmutex->ownerTid, tid)) {
        pmutex->ownerTid = tid;
        pmutex->owned = 1;
        pmutex->count++;
        result = epicsMutexLockOK;
    } else {
        result = epicsMutexLockTimeout;
    }

    status = pthread_mutex_unlock(&pmutex->lock);
    checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdTryLock");
    return result;
}
コード例 #17
0
ファイル: osdMutex.c プロジェクト: ukaea/epics
void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex)
{
    int status;

    status = mutexLock(&pmutex->lock);
    checkStatusQuit(status, "pthread_mutex_lock", "epicsMutexOsdUnlock");

    if ((pmutex->count <= 0) || (pmutex->ownerTid != pthread_self())) {
        errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n");
        status = pthread_mutex_unlock(&pmutex->lock);
        checkStatusQuit(status, "pthread_mutex_unlock", "epicsMutexOsdUnlock");
        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", "epicsMutexOsdUnlock");
}
コード例 #18
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg)
{
    static struct epicsThreadOSD threadOnceComplete;
    #define EPICS_THREAD_ONCE_DONE &threadOnceComplete
    int status;

    epicsThreadInit();
    status = mutexLock(&onceLock);
    if(status) {
        fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n",
            strerror(status));
        exit(-1);
    }

    if (*id != EPICS_THREAD_ONCE_DONE) {
        if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */
            *id = epicsThreadGetIdSelf();    /* mark active */
            status = pthread_mutex_unlock(&onceLock);
            checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
            func(arg);
            status = mutexLock(&onceLock);
            checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce");
            *id = EPICS_THREAD_ONCE_DONE;    /* mark done */
        } else if (*id == epicsThreadGetIdSelf()) {
            status = pthread_mutex_unlock(&onceLock);
            checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
            cantProceed("Recursive epicsThreadOnce() initialization\n");
        } else
            while (*id != EPICS_THREAD_ONCE_DONE) {
                /* Another thread is in the above func(arg) call. */
                status = pthread_mutex_unlock(&onceLock);
                checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce");
                epicsThreadSleep(epicsThreadSleepQuantum());
                status = mutexLock(&onceLock);
                checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce");
            }
    }
    status = pthread_mutex_unlock(&onceLock);
    checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce");
}
コード例 #19
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
static void epicsThreadInit(void)
{
    static pthread_once_t once_control = PTHREAD_ONCE_INIT;
    int status = pthread_once(&once_control,once);
    checkStatusQuit(status,"pthread_once","epicsThreadInit");
}
コード例 #20
0
ファイル: osdThread.c プロジェクト: T-A-R-L-A/EPICS-Base
static void*
find_pri_range(void *arg)
{
priAvailable *prm = arg;
int           min = sched_get_priority_min(prm->policy);
int           max = sched_get_priority_max(prm->policy);
int           low, try;

    if ( -1 == min || -1 == max ) {
        /* something is very wrong; maintain old behavior
         * (warning message if sched_get_priority_xxx() fails
         * and use default policy's sched_priority [even if
         * that is likely to cause epicsThreadCreate to fail
         * because that priority is not suitable for SCHED_FIFO]).
         */
        prm->min_pri = prm->max_pri = -1;
        return 0;
    }


    if ( try_pri(min, prm->policy) ) {
        /* cannot create thread at minimum priority;
         * probably no permission to use SCHED_FIFO
         * at all. However, we still must return
         * a priority range accepted by the SCHED_FIFO
         * policy. Otherwise, epicsThreadCreate() cannot
         * detect the unsufficient permission (EPERM)
         * and fall back to a non-RT thread (because
         * pthread_attr_setschedparam would fail with
         * EINVAL due to the bad priority).
         */
        prm->min_pri = prm->max_pri = min;
        return 0;
    }


    /* Binary search through available priorities.
     * The actually available range may be restricted
     * by resource limitations (but that is ignored
     * by sched_get_priority_max() [linux]).
     */
    low = min;

    while ( low < max ) {
        try = (max+low)/2;
        if ( try_pri(try, prm->policy) ) {
            max = try;
        } else {
            low = try + 1;
        }
    }

    prm->min_pri = min;
    prm->max_pri = try_pri(max, prm->policy) ? max-1 : max;

    return 0;
}

static void findPriorityRange(commonAttr *a_p)
{
priAvailable arg;
pthread_t    id;
void         *dummy;
int          status;

    arg.policy = a_p->schedPolicy;

    status = pthread_create(&id, 0, find_pri_range, &arg);
    checkStatusQuit(status, "pthread_create","epicsThreadInit");

    status = pthread_join(id, &dummy);
    checkStatusQuit(status, "pthread_join","epicsThreadInit");

    a_p->minPriority = arg.min_pri;
    a_p->maxPriority = arg.max_pri;
}
#endif


static void once(void)
{
    epicsThreadOSD *pthreadInfo;
    int status;

    pthread_key_create(&getpthreadInfo,0);
    status = pthread_mutex_init(&onceLock,0);
    checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit");
    status = pthread_mutex_init(&listLock,0);
    checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit");
    pcommonAttr = calloc(1,sizeof(commonAttr));
    if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","epicsThreadInit");
    status = pthread_attr_init(&pcommonAttr->attr);
    checkStatusOnceQuit(status,"pthread_attr_init","epicsThreadInit");
    status = pthread_attr_setdetachstate(
        &pcommonAttr->attr, PTHREAD_CREATE_DETACHED);
    checkStatusOnce(status,"pthread_attr_setdetachstate");
    status = pthread_attr_setscope(&pcommonAttr->attr,PTHREAD_SCOPE_PROCESS);
    if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope");
#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) 
    status = pthread_attr_setschedpolicy(
        &pcommonAttr->attr,SCHED_FIFO);
    checkStatusOnce(status,"pthread_attr_setschedpolicy");
    status = pthread_attr_getschedpolicy(
        &pcommonAttr->attr,&pcommonAttr->schedPolicy);
    checkStatusOnce(status,"pthread_attr_getschedpolicy");
    status = pthread_attr_getschedparam(
        &pcommonAttr->attr,&pcommonAttr->schedParam);
    checkStatusOnce(status,"pthread_attr_getschedparam");

    findPriorityRange(pcommonAttr);

    if(pcommonAttr->maxPriority == -1) {
        pcommonAttr->maxPriority = pcommonAttr->schedParam.sched_priority;
        fprintf(stderr,"sched_get_priority_max failed set to %d\n",
            pcommonAttr->maxPriority);
    }
    if(pcommonAttr->minPriority == -1) {
        pcommonAttr->minPriority = pcommonAttr->schedParam.sched_priority;
        fprintf(stderr,"sched_get_priority_min failed set to %d\n",
            pcommonAttr->maxPriority);
    }
#else
    if(errVerbose) fprintf(stderr,"task priorities are not implemented\n");
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
    pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0);
    status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo);
    checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit");
    status = mutexLock(&listLock);
    checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit");
    ellAdd(&pthreadList,&pthreadInfo->node);
    pthreadInfo->isOnThreadList = 1;
    status = pthread_mutex_unlock(&listLock);
    checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit");
    status = atexit(epicsExitCallAtExits);
    checkStatusOnce(status,"atexit");
    epicsThreadOnceCalled = 1;
}