diff --git a/src/libCom/taskwd/taskwd.c b/src/libCom/taskwd/taskwd.c index 8f8f08c44..668766dfc 100644 --- a/src/libCom/taskwd/taskwd.c +++ b/src/libCom/taskwd/taskwd.c @@ -4,38 +4,24 @@ /* * Original Author: Marty Kraimer * Date: 07-18-91 - * - * 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 - * - * Modification Log: - * ----------------- - * .01 07-24-91 mrk Replacement for special purpose scan watchdog - * .02 05-04-94 mrk Allow user callback to call taskwdRemove - */ - +*/ + +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1991 Regents of the University of California, +and the University of Chicago Board of Governors. + +This software was developed under a United States Government license +described on the COPYRIGHT_Combined file included as part +of this distribution. +**********************************************************************/ + #include #include #include - + #define epicsExportSharedSymbols #include "dbDefs.h" #include "osiThread.h" @@ -48,14 +34,14 @@ typedef void (*MYFUNCPTR)(); struct task_list { - ELLNODE node; - MYFUNCPTR callback; - void *arg; - union { - threadId tid; - void *userpvt; - } id; - int suspended; + ELLNODE node; + MYFUNCPTR callback; + void *arg; + union { + threadId tid; + void *userpvt; + } id; + int suspended; }; static ELLLIST list; @@ -72,13 +58,13 @@ static struct freeList *freeHead=NULL; /* Task delay times (seconds) */ #define TASKWD_DELAY 6.0 - /*forward definitions*/ static void taskwdTask(void); static struct task_list *allocList(void); static void freeList(struct task_list *pt); +static void taskwdInitPvt(void *); -void taskwdInit() +static void taskwdInitPvt(void *arg) { lock = semMutexMustCreate(); anylock = semMutexMustCreate(); @@ -89,11 +75,18 @@ void taskwdInit() "taskwd",threadPriorityLow,threadGetStackSize(threadStackSmall), (THREADFUNC)taskwdTask,0); } +void taskwdInit() +{ + static threadOnceId taskwdOnceFlag = OSITHREAD_ONCE_INIT; + void *arg = 0; + threadOnce(&taskwdOnceFlag,taskwdInitPvt,arg); +} void taskwdInsert(threadId tid,TASKWDFUNCPRR callback,void *arg) { struct task_list *pt; + taskwdInit(); semMutexMustTake(lock); pt = allocList(); ellAdd(&list,(void *)pt); @@ -103,11 +96,12 @@ void taskwdInsert(threadId tid,TASKWDFUNCPRR callback,void *arg) pt->arg = arg; semMutexGive(lock); } - + void taskwdAnyInsert(void *userpvt,TASKWDANYFUNCPRR callback,void *arg) { struct task_list *pt; + taskwdInit(); semMutexMustTake(anylock); pt = allocList(); ellAdd(&anylist,(void *)pt); @@ -121,16 +115,17 @@ void taskwdRemove(threadId tid) { struct task_list *pt; + taskwdInit(); semMutexMustTake(lock); pt = (struct task_list *)ellFirst(&list); while(pt!=NULL) { - if (tid == pt->id.tid) { - ellDelete(&list,(void *)pt); - freeList(pt); - semMutexGive(lock); - return; - } - pt = (struct task_list *)ellNext((ELLNODE *)pt); + if (tid == pt->id.tid) { + ellDelete(&list,(void *)pt); + freeList(pt); + semMutexGive(lock); + return; + } + pt = (struct task_list *)ellNext((ELLNODE *)pt); } semMutexGive(lock); errMessage(-1,"taskwdRemove failed"); @@ -140,16 +135,17 @@ void taskwdAnyRemove(void *userpvt) { struct task_list *pt; + taskwdInit(); semMutexMustTake(anylock); pt = (struct task_list *)ellFirst(&anylist); while(pt!=NULL) { - if (userpvt == pt->id.userpvt) { - ellDelete(&anylist,(void *)pt); - freeList(pt); - semMutexGive(anylock); - return; - } - pt = (struct task_list *)ellNext((void *)pt); + if (userpvt == pt->id.userpvt) { + ellDelete(&anylist,(void *)pt); + freeList(pt); + semMutexGive(anylock); + return; + } + pt = (struct task_list *)ellNext((void *)pt); } semMutexGive(anylock); errMessage(-1,"taskwdanyRemove failed"); @@ -160,46 +156,46 @@ static void taskwdTask(void) struct task_list *pt,*next; while(TRUE) { - if(taskwdOn) { - semMutexMustTake(lock); - pt = (struct task_list *)ellFirst(&list); - while(pt) { - next = (struct task_list *)ellNext((void *)pt); - if(threadIsSuspended(pt->id.tid)) { - char message[100]; + if(taskwdOn) { + semMutexMustTake(lock); + pt = (struct task_list *)ellFirst(&list); + while(pt) { + next = (struct task_list *)ellNext((void *)pt); + if(threadIsSuspended(pt->id.tid)) { + char message[100]; - if(!pt->suspended) { - struct task_list *ptany; + if(!pt->suspended) { + struct task_list *ptany; - pt->suspended = TRUE; - sprintf(message,"task %p suspended",pt->id.tid); - errMessage(-1,message); - ptany = (struct task_list *)ellFirst(&anylist); - while(ptany) { - if(ptany->callback) { - TASKWDANYFUNCPRR pcallback = pt->callback; - (pcallback)(ptany->arg,pt->id.tid); - } - ptany = (struct task_list *)ellNext((ELLNODE *)ptany); - } - if(pt->callback) { - TASKWDFUNCPRR pcallback = pt->callback; - void *arg = pt->arg; + pt->suspended = TRUE; + sprintf(message,"task %p suspended",pt->id.tid); + errMessage(-1,message); + ptany = (struct task_list *)ellFirst(&anylist); + while(ptany) { + if(ptany->callback) { + TASKWDANYFUNCPRR pcallback = pt->callback; + (pcallback)(ptany->arg,pt->id.tid); + } + ptany = (struct task_list *)ellNext((ELLNODE *)ptany); + } + if(pt->callback) { + TASKWDFUNCPRR pcallback = pt->callback; + void *arg = pt->arg; - /*Must allow callback to call taskwdRemove*/ - semMutexGive(lock); - (pcallback)(arg); - /*skip rest because we have unlocked*/ - break; - } - } - } else { - pt->suspended = FALSE; - } - pt = next; - } - semMutexGive(lock); - } + /*Must allow callback to call taskwdRemove*/ + semMutexGive(lock); + (pcallback)(arg); + /*skip rest because we have unlocked*/ + break; + } + } + } else { + pt->suspended = FALSE; + } + pt = next; + } + semMutexGive(lock); + } threadSleep(TASKWD_DELAY); } } @@ -210,12 +206,12 @@ static struct task_list *allocList(void) semMutexMustTake(alloclock); if(freeHead) { - pt = (struct task_list *)freeHead; - freeHead = freeHead->next; + pt = (struct task_list *)freeHead; + freeHead = freeHead->next; } else pt = calloc(1,sizeof(struct task_list)); if(pt==NULL) { - errMessage(0,"taskwd failed on call to calloc\n"); - exit(1); + errMessage(0,"taskwd failed on call to calloc\n"); + exit(1); } semMutexGive(alloclock); return(pt); diff --git a/src/libCom/taskwd/taskwd.h b/src/libCom/taskwd/taskwd.h index fc9f37d2e..9e0b5a9bb 100644 --- a/src/libCom/taskwd/taskwd.h +++ b/src/libCom/taskwd/taskwd.h @@ -5,32 +5,19 @@ /* * Original Author: Marty Kraimer * Date: 07-18-91 - * - * 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 - * - * Modification Log: - * ----------------- - * .01 12-12-91 mrk Initial version */ + +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1991 Regents of the University of California, +and the University of Chicago Board of Governors. + +This software was developed under a United States Government license +described on the COPYRIGHT_Combined file included as part +of this distribution. +**********************************************************************/ #ifndef INCtaskwdh #define INCtaskwdh 1 @@ -40,23 +27,19 @@ typedef void (*TASKWDFUNCPRR)(void *parm); typedef void (*TASKWDANYFUNCPRR)(void *parm,threadId tid); -#if defined(__STDC__) || defined(__cplusplus) + #ifdef __cplusplus extern "C" { #endif + epicsShareFunc void taskwdInit(void); epicsShareFunc void taskwdInsert(threadId tid, TASKWDFUNCPRR callback,void *arg); epicsShareFunc void taskwdAnyInsert(void *userpvt, TASKWDANYFUNCPRR callback,void *arg); epicsShareFunc void taskwdRemove(threadId tid); epicsShareFunc void taskwdAnyRemove(void *userpvt); + #ifdef __cplusplus } #endif -#else -epicsShareFunc void taskwdInit(); -epicsShareFunc void taskwdInsert(); -epicsShareFunc void taskwdAnyInsert(); -epicsShareFunc void taskwdRemove(); -epicsShareFunc void taskwdAnyRemove(); -#endif /*__STDC__*/ + #endif /*INCtaskwdh*/