use threadOnce; add lazy init
This commit is contained in:
@@ -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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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*/
|
||||
|
||||
Reference in New Issue
Block a user