From 7beea091b1999648588df8f59a838c760c3d06f9 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Fri, 28 Oct 2005 12:59:26 +0000 Subject: [PATCH] change way to handle EPERM error --- src/libCom/osi/os/posix/osdThread.c | 108 +++++++++++----------------- 1 file changed, 43 insertions(+), 65 deletions(-) diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c index 5a47184cc..c4e2f57e6 100644 --- a/src/libCom/osi/os/posix/osdThread.c +++ b/src/libCom/osi/os/posix/osdThread.c @@ -143,7 +143,7 @@ static void myAtExit(void) pthread_mutex_destroy(&onceLock); pthread_key_delete(getpthreadInfo); } - + static int getOssPriorityValue(epicsThreadOSD *pthreadInfo) { double maxPriority,minPriority,slope,oss; @@ -156,6 +156,30 @@ static int getOssPriorityValue(epicsThreadOSD *pthreadInfo) oss = (double)pthreadInfo->osiPriority * slope + minPriority; return((int)oss); } +static void setSchedulingPolicy(epicsThreadOSD *pthreadInfo,int policy) +{ +#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) + int status; + + status = pthread_attr_getschedparam( + &pthreadInfo->attr,&pthreadInfo->schedParam); + checkStatusOnce(status,"pthread_attr_getschedparam"); + pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo); + status = pthread_attr_setschedpolicy( + &pthreadInfo->attr,policy); + if(status) { + checkStatusOnce(status,"pthread_attr_setschedpolicy"); + } + status = pthread_attr_setschedparam( + &pthreadInfo->attr,&pthreadInfo->schedParam); + if(status) { + checkStatusOnce(status,"pthread_attr_setschedparam"); + } + status = pthread_attr_setinheritsched( + &pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED); + checkStatusOnce(status,"pthread_attr_setinheritsched"); +#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ +} static epicsThreadOSD * create_threadInfo(const char *name) { @@ -167,34 +191,6 @@ static epicsThreadOSD * create_threadInfo(const char *name) return pthreadInfo; } -static epicsThreadOSD * init_threadInfo1(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadOSD *pthreadInfo; - int status; - - pthreadInfo = create_threadInfo(name); - pthreadInfo->createFunc = funptr; - pthreadInfo->createArg = parm; - status = pthread_attr_init(&pthreadInfo->attr); - checkStatusOnce(status,"pthread_attr_init"); - if(status) return 0; - status = pthread_attr_setdetachstate( - &pthreadInfo->attr, PTHREAD_CREATE_DETACHED); - checkStatusOnce(status,"pthread_attr_setdetachstate"); -#if defined (_POSIX_THREAD_ATTR_STACKSIZE) -#if ! defined (OSITHREAD_USE_DEFAULT_STACK) - status = pthread_attr_setstacksize( &pthreadInfo->attr,(size_t)stackSize); - checkStatusOnce(status,"pthread_attr_setstacksize"); -#endif /*OSITHREAD_USE_DEFAULT_STACK*/ -#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ - status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS); - if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); - pthreadInfo->osiPriority = priority; - return(pthreadInfo); -} - static epicsThreadOSD * init_threadInfo(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr,void *parm) @@ -220,25 +216,7 @@ static epicsThreadOSD * init_threadInfo(const char *name, status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS); if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); pthreadInfo->osiPriority = priority; -#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) - status = pthread_attr_getschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - checkStatusOnce(status,"pthread_attr_getschedparam"); - pthreadInfo->schedParam.sched_priority = getOssPriorityValue(pthreadInfo); - status = pthread_attr_setschedpolicy( - &pthreadInfo->attr,SCHED_FIFO); - if(status) { - checkStatusOnce(status,"pthread_attr_setschedpolicy"); - } - status = pthread_attr_setschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - if(status) { - checkStatusOnce(status,"pthread_attr_setschedparam"); - } - status = pthread_attr_setinheritsched( - &pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED); - checkStatusOnce(status,"pthread_attr_setinheritsched"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ + setSchedulingPolicy(pthreadInfo,SCHED_FIFO); return(pthreadInfo); } @@ -415,10 +393,10 @@ epicsThreadId epicsThreadCreate(const char *name, if(pthreadInfo==0) return 0; status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, start_routine,pthreadInfo); - if(status==1){ /* no permission to create such a thread, non-root user */ - pthreadInfo = init_threadInfo1(name,priority,stackSize,funptr,parm); - if(pthreadInfo==0) return 0; - status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, + if(status==EPERM){ + /* change scheduling policy and try again */ + setSchedulingPolicy(pthreadInfo,SCHED_OTHER); + status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, start_routine,pthreadInfo); } checkStatus(status,"pthread_create"); @@ -457,7 +435,6 @@ static epicsThreadOSD *createImplicit(void) { struct sched_param param; int policy; - int priority = 0; if(pthread_getschedparam(tid,&policy,¶m) == 0) pthreadInfo->osiPriority = (param.sched_priority - pcommonAttr->minPriority) * 100.0 / @@ -655,22 +632,23 @@ void epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size) static void showThreadInfo(epicsThreadOSD *pthreadInfo,unsigned int level) { if(!pthreadInfo) { - fprintf(epicsGetStdout()," NAME EPICS ID PTHREAD ID OSIPRI OSSPRI STATE\n"); - } - else { + fprintf(epicsGetStdout()," NAME EPICS ID " + "PTHREAD ID OSIPRI OSSPRI STATE\n"); + } else { struct sched_param param; int policy; int priority = 0; - if ((pthreadInfo->tid != 0) - && (pthread_getschedparam(pthreadInfo->tid,&policy,¶m) == 0)) - priority = param.sched_priority; - fprintf(epicsGetStdout(),"%16.16s %12p %12lu %3d%8d %8.8s\n", pthreadInfo->name,(void *) - pthreadInfo,(unsigned long)pthreadInfo->tid, - pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended?"SUSPEND":"OK"); - if(level>0) - ; /* more info */ + if(pthreadInfo->tid) { + int status; + status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m); + if(!status) priority = param.sched_priority; + } + fprintf(epicsGetStdout(),"%16.16s %12p %12lu %3d%8d %8.8s\n", + pthreadInfo->name,(void *) + pthreadInfo,(unsigned long)pthreadInfo->tid, + pthreadInfo->osiPriority,priority, + pthreadInfo->isSuspended?"SUSPEND":"OK"); } }