From cda567985cc4981e1c1cb3f4c0910c8a14ac7072 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Thu, 17 Feb 2000 20:59:17 +0000 Subject: [PATCH] moved taskwd.c taskwd.h from src/db to src/libCom/taskwd --- src/libCom/Makefile | 5 + src/libCom/taskwd/taskwd.c | 230 +++++++++++++++++++++++++++++++++++++ src/libCom/taskwd/taskwd.h | 55 +++++++++ 3 files changed, 290 insertions(+) create mode 100644 src/libCom/taskwd/taskwd.c create mode 100644 src/libCom/taskwd/taskwd.h diff --git a/src/libCom/Makefile b/src/libCom/Makefile index 32175b23e..766a41950 100644 --- a/src/libCom/Makefile +++ b/src/libCom/Makefile @@ -60,6 +60,7 @@ INC += tsStamp.h INC += osiMutex.h INC += osiEvent.h + SRCS += osdSock.c SRCS += osiSock.c SRCS += osdAssert.c @@ -151,6 +152,10 @@ SRC_DIRS += $(LIBCOM)/logClient INC += logClient.h SRCS += logClient.c +SRC_DIRS += $(LIBCOM)/taskwd +INC += taskwd.h +SRCS += taskwd.c + SRC_DIRS += $(LIBCOM)/timer INC += osiTimer.h SRCS += osiTimer.cpp diff --git a/src/libCom/taskwd/taskwd.c b/src/libCom/taskwd/taskwd.c new file mode 100644 index 000000000..81387cf2f --- /dev/null +++ b/src/libCom/taskwd/taskwd.c @@ -0,0 +1,230 @@ +/* taskwd.c */ +/* share/src/db @(#)taskwd.c 1.7 7/11/94 */ +/* tasks and subroutines for a general purpose task watchdog */ +/* + * 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 + */ + +#include +#include +#include + +#include "dbDefs.h" +#include "osiThread.h" +#include "osiSem.h" +#include "errlog.h" +#include "ellLib.h" +#include "errMdef.h" +#include "taskwd.h" + +typedef void (*MYFUNCPTR)(); + +struct task_list { + ELLNODE node; + MYFUNCPTR callback; + void *arg; + union { + threadId tid; + void *userpvt; + } id; + int suspended; +}; + +static ELLLIST list; +static ELLLIST anylist; +static semMutexId lock; +static semMutexId anylock; +static semMutexId alloclock; +static threadId taskwdid=0; +volatile int taskwdOn=TRUE; +struct freeList{ + struct freeList *next; +}; +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); + +void taskwdInit() +{ + lock = semMutexMustCreate(); + anylock = semMutexMustCreate(); + alloclock = semMutexMustCreate(); + ellInit(&list); + ellInit(&anylist); + taskwdid = threadCreate( + "taskwd",threadPriorityLow,threadGetStackSize(threadStackSmall), + (THREADFUNC)taskwdTask,0); +} + +void taskwdInsert(threadId tid,TASKWDFUNCPRR callback,void *arg) +{ + struct task_list *pt; + + semMutexMustTake(lock); + pt = allocList(); + ellAdd(&list,(void *)pt); + pt->suspended = FALSE; + pt->id.tid = tid; + pt->callback = callback; + pt->arg = arg; + semMutexGive(lock); +} + +void taskwdAnyInsert(void *userpvt,TASKWDANYFUNCPRR callback,void *arg) +{ + struct task_list *pt; + + semMutexMustTake(anylock); + pt = allocList(); + ellAdd(&anylist,(void *)pt); + pt->id.userpvt = userpvt; + pt->callback = callback; + pt->arg = arg; + semMutexGive(anylock); +} + +void taskwdRemove(threadId tid) +{ + struct task_list *pt; + + 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); + } + semMutexGive(lock); + errMessage(-1,"taskwdRemove failed"); +} + +void taskwdAnyRemove(void *userpvt) +{ + struct task_list *pt; + + 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); + } + semMutexGive(anylock); + errMessage(-1,"taskwdanyRemove failed"); +} + +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(!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; + + /*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); + } +} + +static struct task_list *allocList(void) +{ + struct task_list *pt; + + semMutexMustTake(alloclock); + if(freeHead) { + 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); + } + semMutexGive(alloclock); + return(pt); +} + +static void freeList(struct task_list *pt) +{ + + semMutexMustTake(alloclock); + ((struct freeList *)pt)->next = freeHead; + freeHead = (struct freeList *)pt; + semMutexGive(alloclock); +} diff --git a/src/libCom/taskwd/taskwd.h b/src/libCom/taskwd/taskwd.h new file mode 100644 index 000000000..9a4caa0de --- /dev/null +++ b/src/libCom/taskwd/taskwd.h @@ -0,0 +1,55 @@ +/* taskwd.h */ +/* share/epicsH/taskwd.h $Id$ */ + +/* includes for general purpose taskwd tasks */ +/* + * 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 +*/ + +#ifndef INCtaskwdh +#define INCtaskwdh 1 + +#include "osiThread.h" + +typedef void (*TASKWDFUNCPRR)(void *parm); +typedef void (*TASKWDANYFUNCPRR)(void *parm,threadId tid); +#ifdef __STDC__ +void taskwdInit(); +void taskwdInsert(threadId tid, TASKWDFUNCPRR callback,void *arg); +void taskwdAnyInsert(void *userpvt, TASKWDANYFUNCPRR callback,void *arg); +void taskwdRemove(threadId tid); +void taskwdAnyRemove(void *userpvt); +#else +void taskwdInit(); +void taskwdInsert(); +void taskwdAnyInsert(); +void taskwdRemove(); +void taskwdAnyRemove(); +#endif /*__STDC__*/ +#endif /*INCtaskwdh*/