Fixed many bugs

This commit is contained in:
Marty Kraimer
1996-05-03 14:11:06 +00:00
parent bbbc3b6329
commit 3e0445f2ad
5 changed files with 360 additions and 273 deletions

View File

@@ -385,7 +385,10 @@ static void getOptions(DBADDR *paddr,void **poriginal,long *options,void *pflin)
struct rset *dbGetRset(struct dbAddr *paddr)
{
return(((struct dbFldDes *)paddr->pfldDes)->pdbRecDes->prset);
struct dbFldDes *pfldDes = (struct dbFldDes *)paddr->pfldDes;
if(!pfldDes) return(0);
return(pfldDes->pdbRecDes->prset);
}
int dbIsValueField(struct dbFldDes *pdbFldDes)
@@ -422,10 +425,14 @@ long dbScanPassive(dbCommon *pfrom, dbCommon *pto)
/*KLUDGE: Following needed so that dbPutLink to PROC field works correctly*/
long dbScanLink(dbCommon *pfrom, dbCommon *pto)
{
long status;
long status;
unsigned char pact;
if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto);
pact = pfrom->pact;
pfrom->pact = TRUE;
status = dbProcess(pto);
pfrom->pact = pact;
return(status);
}
@@ -846,7 +853,7 @@ long dbGet(DBADDR *paddr,short dbrType,void *pbuffer,long *options,
if(nRequest) {
if(no_elements<(*nRequest)) *nRequest = no_elements;
n = no_elements;
n = *nRequest;
} else {
n = 1;
}
@@ -858,7 +865,9 @@ long dbGet(DBADDR *paddr,short dbrType,void *pbuffer,long *options,
return(S_db_badDbrtype);
}
/* convert database field and place it in the buffer */
if(pfl!=NULL) {
if(n<=0) {
;/*do nothing*/
} else if(pfl!=NULL) {
DBADDR localAddr;
localAddr = *paddr; /*Structure copy*/
@@ -1069,7 +1078,7 @@ long dbPut(DBADDR *paddr,short dbrType,void *pbuffer,long nRequest)
status = putSpecial(paddr,0);
if(status) return(status);
}
if(no_elements<=1) {
if((no_elements<=1) && (!prset || !(prset->put_array_info))) {
status = (*dbFastPutConvertRoutine[dbrType][field_type])
(pbuffer,paddr->pfield, paddr);
} else {

View File

@@ -89,10 +89,10 @@ void dbCaRemoveLink( struct link *plink)
if(!pca) return;
semTake(caListSem,WAIT_FOREVER);
pca->link_action = CA_DELETE;
if(!pca->link_action){/*If not on work list add it*/
ellAdd(&caList,&pca->node);
}
pca->link_action = CA_DELETE;
plink->value.pv_link.pvt = 0;
pca->plink = 0;
semGive(caListSem);
@@ -133,7 +133,10 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
pca->pgetString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
semGive(pca->lock);
semTake(caListSem,WAIT_FOREVER);
pca->link_action = CA_MONITOR_STRING;
if(!pca->link_action){/*If not on work list add it*/
pca->link_action = CA_MONITOR_STRING;
ellAdd(&caList,&pca->node);
}
semGive(caListSem);
semGive(caWakeupSem);
semStatus = semTake(pca->lock,WAIT_FOREVER);
@@ -158,7 +161,8 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
if(!nelements || *nelements == 1){
pconvert=
dbFastGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
status = (*(pconvert))(pca->pgetNative, pdest, 0);
/*Ignore error routine*/
(*(pconvert))(pca->pgetNative, pdest, 0);
}else{
unsigned long ntoget = *nelements;
struct db_addr dbAddr;
@@ -170,7 +174,8 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
dbAddr.pfield = pca->pgetNative;
/*Following will only be used for pca->dbrType == DBR_STRING*/
dbAddr.field_size = MAX_STRING_SIZE;
status = (*(pconvert))(&dbAddr,pdest,nelements,ntoget,0);
/*Ignore error routine*/
(*(pconvert))(&dbAddr,pdest,ntoget,ntoget,0);
}
done:
if(psevr) *psevr = pca->sevr;
@@ -242,16 +247,15 @@ long dbCaPutLink(struct link *plink,short dbrType,
semGive(caWakeupSem);
return(status);
}
static void caEventHandler(struct event_handler_args arg)
static void eventCallback(struct event_handler_args arg)
{
caLink *pca = (caLink *)arg.usr;
struct link *plink;
long size;
if(!pca) {
epicsPrintf("caEventHandler why was arg.usr NULL\n");
epicsPrintf("eventCallback why was arg.usr NULL\n");
return;
}
plink = pca->plink;
@@ -259,16 +263,18 @@ static void caEventHandler(struct event_handler_args arg)
dbCommon *precord = 0;
if(plink) precord = (dbCommon *)plink->value.pv_link.precord;
if(precord)
epicsPrintf("dbCa: caEventHandler record %s error %s\n",
if(precord) {
if(arg.status!=ECA_NORDACCESS)
epicsPrintf("dbCa: eventCallback record %s error %s\n",
precord->name,ca_message(arg.status));
else
epicsPrintf("dbCa: caEventHandler error %s\n",
} else {
epicsPrintf("dbCa: eventCallback error %s\n",
ca_message(arg.status));
}
return;
}
if(!arg.dbr) {
epicsPrintf("caEventHandler why was arg.dbr NULL\n");
epicsPrintf("eventCallback why was arg.dbr NULL\n");
return;
}
semTake(pca->lock,WAIT_FOREVER);
@@ -289,7 +295,7 @@ static void caEventHandler(struct event_handler_args arg)
pca->gotInNative = TRUE;
break;
default:
errMessage(-1,"dbCa: caEventHandler Logic Error\n");
errMessage(-1,"dbCa: eventCallback Logic Error\n");
break;
}
pca->sevr=(unsigned short)((struct dbr_sts_double *)arg.dbr)->severity;
@@ -301,13 +307,36 @@ static void caEventHandler(struct event_handler_args arg)
if(precord) {
if((ppv_link->pvlMask&pvlOptCP)
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
scanOnce(ppv_link->precord);
scanOnce(precord);
}
}
semGive(pca->lock);
}
static void dbCaLinkConnectionHandler(struct connection_handler_args arg)
static void accessRightsCallback(struct access_rights_handler_args arg)
{
caLink *pca = (caLink *)ca_puser(arg.chid);
struct link *plink;
if(!pca) {
epicsPrintf("accessRightsCallback why was arg.usr NULL\n");
return;
}
if(ca_read_access(arg.chid) || ca_write_access(arg.chid)) return;
plink = pca->plink;
if(plink) {
struct pv_link *ppv_link = &(plink->value.pv_link);
dbCommon *precord = ppv_link->precord;
if(precord) {
if((ppv_link->pvlMask&pvlOptCP)
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
scanOnce(precord);
}
}
}
static void connectionCallback(struct connection_handler_args arg)
{
caLink *pca;
int status;
@@ -342,13 +371,13 @@ static void dbCaLinkConnectionHandler(struct connection_handler_args arg)
pca->pputNative = dbCalloc(pca->nelements,element_size);
status = ca_add_array_event(
ca_field_type(arg.chid)+DBR_STS_STRING, ca_element_count(arg.chid),
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
if(status!=ECA_NORMAL)
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
ca_message(status));
if(pca->pgetString) {
status = ca_add_array_event(DBR_STS_STRING,1,
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
if(status!=ECA_NORMAL)
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
ca_message(status));
@@ -385,10 +414,17 @@ void dbCaTask()
status = ca_search_and_connect(
pca->plink->value.pv_link.pvname,
&(pca->chid),
dbCaLinkConnectionHandler,(void *)pca);
if(status!=ECA_NORMAL)
connectionCallback,(void *)pca);
if(status!=ECA_NORMAL) {
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
ca_message(status));
break;
}
status = ca_replace_access_rights_event(pca->chid,
accessRightsCallback);
if(status!=ECA_NORMAL)
epicsPrintf("dbCaTask ca_replace_access_rights_event %s\n",
ca_message(status));
break;
case CA_DELETE:
if(pca->chid) ca_clear_channel(pca->chid);
@@ -422,7 +458,7 @@ void dbCaTask()
case CA_MONITOR_STRING:
if(ca_state(pca->chid) == cs_conn){
status = ca_add_array_event(DBR_STS_STRING,1,
pca->chid, caEventHandler,pca,0.0,0.0,0.0,0);
pca->chid, eventCallback,pca,0.0,0.0,0.0,0);
if(status!=ECA_NORMAL)
epicsPrintf("dbCaTask ca_add_array_event %s\n",
ca_message(status));

View File

@@ -45,9 +45,8 @@
#include <recSup.h>
#include <recGbl.h>
/* DATABASE ACCESS GET CONVERSION SUPPORT */
static long getStringString (
DBADDR *paddr, void *pto, long nRequest, long no_elements, long offset)
{
@@ -90,15 +89,21 @@ static long getStringChar(
if(sscanf(psrc,"%hd",&value) == 1) {
*pbuffer = (char)value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = '0';
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%hd",&value) == 1) {
*pbuffer = (char)value;
} else if(strlen(psrc) == 0) {
*pbuffer = '0';
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -121,15 +126,21 @@ static long getStringUchar(
if(sscanf(psrc,"%hu",&value) == 1) {
*pbuffer = (unsigned char)value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = '0';
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%hu",&value) == 1) {
*pbuffer = (unsigned char)value;
} else if(strlen(psrc) == 0) {
*pbuffer = '0';
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -152,15 +163,21 @@ static long getStringShort(
if(sscanf(psrc,"%hd",&value) == 1) {
*pbuffer = value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%hd",&value) == 1) {
*pbuffer = value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -183,15 +200,21 @@ static long getStringUshort(
if(sscanf(psrc,"%hu",&value) == 1) {
*pbuffer = value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%hu",&value) == 1) {
*pbuffer = value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -214,15 +237,21 @@ static long getStringLong(
if(sscanf(psrc,"%ld",&value) == 1) {
*pbuffer = value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%ld",&value) == 1) {
*pbuffer = value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -239,21 +268,29 @@ static long getStringUlong(
{
unsigned long *pbuffer = (unsigned long *)pto;
char *psrc=(char *)paddr->pfield;
unsigned long value;
double value;
/*Convert to double first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned long as double*/
if(nRequest==1 && offset==0) {
if(sscanf(psrc,"%lu",&value) == 1) {
*pbuffer = value;
if(sscanf(psrc,"%lf",&value) == 1) {
*pbuffer = (unsigned long)value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
return(0);
} else {
return(-1);
}
else return(-1);
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%lu",&value) == 1) {
*pbuffer = value;
if(sscanf(psrc,"%lf",&value) == 1) {
*pbuffer = (unsigned long)value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -276,16 +313,21 @@ static long getStringFloat(
if(sscanf(psrc,"%f",&value) == 1) {
*pbuffer = value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0.0;
return(0);
} else {
return(-1);
return(-1);
}
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%f",&value) == 1) {
*pbuffer = value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0.0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -308,16 +350,21 @@ static long getStringDouble(
if(sscanf(psrc,"%lf",&value) == 1) {
*pbuffer = value;
return(0);
} else if(strlen(psrc) == 0) {
*pbuffer = 0.0;
return(0);
} else {
return(-1);
return(-1);
}
}
psrc += MAX_STRING_SIZE*offset;
while (nRequest) {
if(sscanf(psrc,"%lf",&value) == 1) {
*pbuffer = value;
} else if(strlen(psrc) == 0) {
*pbuffer = 0.0;
} else {
return(-1);
return(-1);
}
pbuffer++;
if(++offset==no_elements)
@@ -1504,9 +1551,10 @@ static long getFloatString(
float *psrc=(float *)(paddr->pfield);
long status = 0;
int precision = 0;
struct rset *prset;
struct rset *prset = 0;
if((prset=dbGetRset(paddr)) && (prset->get_precision))
if(paddr) prset = dbGetRset(paddr);
if(prset && (prset->get_precision))
status = (*prset->get_precision)(paddr,&precision);
else
status=S_db_precision;
@@ -1627,17 +1675,14 @@ static long getFloatUlong(
{
unsigned long *pbuffer = (unsigned long *)pto;
float *psrc=(float *)(paddr->pfield);
long ltemp; /*vxWorks does not support float to unsigned long*/
if(nRequest==1 && offset==0) {
ltemp = *psrc;
*pbuffer = ltemp;
*pbuffer = *psrc;
return(0);
}
psrc += offset;
while (nRequest) {
ltemp = *psrc++;
*pbuffer++ = ltemp;
*pbuffer++ = *psrc++;
if(++offset==no_elements) psrc=(float *)paddr->pfield;
nRequest--;
}
@@ -1708,9 +1753,10 @@ static long getDoubleString(
double *psrc=(double *)(paddr->pfield);
long status = 0;
int precision = 0;
struct rset *prset;
struct rset *prset = 0;
if((prset=dbGetRset(paddr)) && (prset->get_precision))
if(paddr) prset = dbGetRset(paddr);
if(prset && (prset->get_precision))
status = (*prset->get_precision)(paddr,&precision);
else
status=S_db_precision;
@@ -1831,17 +1877,14 @@ static long getDoubleUlong(
{
unsigned long *pbuffer = (unsigned long *)pto;
double *psrc=(double *)(paddr->pfield);
long ltemp; /*vxWorks does not support double to unsigned long*/
if(nRequest==1 && offset==0) {
ltemp = *psrc;
*pbuffer = ltemp;
*pbuffer = *psrc;
return(0);
}
psrc += offset;
while (nRequest) {
ltemp = *psrc++;
*pbuffer++ = ltemp;
*pbuffer++ = *psrc++;
if(++offset==no_elements) psrc=(double *)paddr->pfield;
nRequest--;
}
@@ -2268,21 +2311,19 @@ static long putStringUshort(
{
char *pbuffer = (char *)pfrom;
unsigned short *pdest=(unsigned short *)paddr->pfield;
float value;
unsigned short value;
/*Convert to float first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned short as float*/
if(nRequest==1 && offset==0) {
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
return(0);
}
else return(-1);
}
pdest += offset;
while (nRequest) {
if(sscanf(pbuffer,"%f",&value) == 1) {
*pdest = (unsigned short)value;
if(sscanf(pbuffer,"%hu",&value) == 1) {
*pdest = value;
} else {
return(-1);
}
@@ -3721,10 +3762,11 @@ static long putFloatString(
char *pdest=(char *)(paddr->pfield);
long status = 0;
int precision = 0;
struct rset *prset;
struct rset *prset = 0;
short size=paddr->field_size;
if((prset=dbGetRset(paddr)) && (prset->get_precision))
if(paddr) prset = dbGetRset(paddr);
if(prset && (prset->get_precision))
status = (*prset->get_precision)(paddr,&precision);
else
status=S_db_precision;
@@ -3846,17 +3888,14 @@ static long putFloatUlong(
{
float *pbuffer = (float *)pfrom;
unsigned long *pdest=(unsigned long *)(paddr->pfield);
long ltemp;/*vxWorks does not support float to unsigned long*/
if(nRequest==1 && offset==0) {
ltemp = *pbuffer;
*pdest = ltemp;
*pdest = *pbuffer;
return(0);
}
pdest += offset;
while (nRequest) {
ltemp = *pbuffer++;
*pdest++ = ltemp;
*pdest++ = *pbuffer++;
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
nRequest--;
}
@@ -3927,10 +3966,11 @@ static long putDoubleString(
char *pdest=(char *)(paddr->pfield);
long status = 0;
int precision = 0;
struct rset *prset;
struct rset *prset = 0;
short size=paddr->field_size;
if((prset=dbGetRset(paddr)) && (prset->get_precision))
if(paddr) prset = dbGetRset(paddr);
if(prset && (prset->get_precision))
status = (*prset->get_precision)(paddr,&precision);
else
status=S_db_precision;
@@ -4052,17 +4092,14 @@ static long putDoubleUlong(
{
double *pbuffer = (double *)pfrom;
unsigned long *pdest=(unsigned long *)(paddr->pfield);
long ltemp;/*vxWorks does not support double to unsigned long*/
if(nRequest==1 && offset==0) {
ltemp = *pbuffer;
*pdest = ltemp;
*pdest = *pbuffer;
return(0);
}
pdest += offset;
while (nRequest) {
ltemp = *pbuffer++;
*pdest++ = ltemp;
*pdest++ = *pbuffer++;
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
nRequest--;
}

View File

@@ -115,7 +115,10 @@ static long cvt_st_c(
*to = (char) value;
return(0);
}
if(strlen(from) == 0) {
*to = '0';
return(0);
}
return(-1); /* Change to SYMBOL */
}
@@ -125,10 +128,14 @@ static long cvt_st_uc(
unsigned char *to,
struct dbAddr *paddr)
{
short value;
unsigned short value;
if (sscanf(from, "%hu", &value) == 1) {
*to = (unsigned char) value;
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = '0';
return(0);
}
@@ -147,6 +154,10 @@ static long cvt_st_s(
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = 0;
return(0);
}
return(-1); /* Change to SYMBOL */
}
@@ -157,12 +168,16 @@ static long cvt_st_us(
unsigned short *to,
struct dbAddr *paddr)
{
short value;
unsigned short value;
if (sscanf(from, "%hu", &value) == 1) {
*to = (unsigned short) value;
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = 0;
return(0);
}
return(-1); /* Change to SYMBOL */
}
@@ -179,6 +194,10 @@ static long cvt_st_l(
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = 0;
return(0);
}
return(-1); /* Change to SYMBOL */
}
@@ -189,10 +208,16 @@ static long cvt_st_ul(
unsigned long *to,
struct dbAddr *paddr)
{
unsigned long value;
double value;
if (sscanf(from, "%lu", &value) == 1) {
*to = value;
/*Convert to double first so that numbers like 1.0e3 convert properly*/
/*Problem was old database access said to get unsigned long as double*/
if (sscanf(from, "%lf", &value) == 1) {
*to = (unsigned long)value;
return(0);
}
if(strlen(from) == 0) {
*to = 0;
return(0);
}
@@ -211,6 +236,10 @@ static long cvt_st_f(
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = 0.0;
return(0);
}
return(-1); /* Change to SYMBOL */
}
@@ -227,6 +256,10 @@ static long cvt_st_d(
*to = value;
return(0);
}
if(strlen(from) == 0) {
*to = 0.0;
return(0);
}
return(-1); /* Change to SYMBOL */
}

View File

@@ -1,5 +1,4 @@
/* dbScan.c */
/* base/src/db $Id$ */
/* tasks and subroutines to scan the database */
/*
* Original Author: Bob Dalesio
@@ -40,6 +39,7 @@
* .09 02-03-94 mrk If scanAdd fails set precord->scan=SCAN_PASSIVE
* .10 02-22-94 mrk Make init work if 1st record has 28 char name
* .11 05-04-94 mrk Call taskwdRemove only if spawing again
* .12 05-02-96 mrk Allow multiple priority event scan
*/
#include <vxWorks.h>
@@ -73,66 +73,65 @@
extern struct dbBase *pdbbase;
/* SCAN ONCE */
int onceQueueSize = 256;
int onceQueueSize = 1000;
static SEM_ID onceSem;
static RING_ID onceQ;
static int onceTaskId;
/*all other scan types */
struct scan_list{
typedef struct scan_list{
FAST_LOCK lock;
ELLLIST list;
short modified;/*has list been modified?*/
long ticks; /*ticks per period for periodic*/
};
}scan_list;
/*scan_elements are allocated and the address stored in dbCommon.spvt*/
struct scan_element{
typedef struct scan_element{
ELLNODE node;
struct scan_list *pscan_list;
scan_list *pscan_list;
struct dbCommon *precord;
};
}scan_element;
int volatile scanRestart=FALSE;
/* PERIODIC SCANNER */
static int nPeriodic=0;
static struct scan_list **papPeriodic; /* pointer to array of pointers*/
static int *periodicTaskId; /*array of integers after allocation*/
static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
"Low","Medium","High"};
/* EVENT */
#define MAX_EVENTS 256
#define EVENT_QUEUE_SIZE 1000
static struct scan_list *papEvent[MAX_EVENTS];/*array of pointers*/
static SEM_ID eventSem;
static RING_ID eventQ;
static int eventTaskId;
typedef struct event_scan_list {
CALLBACK callback;
scan_list scan_list;
}event_scan_list;
static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
/* IO_EVENT*/
struct io_scan_list {
typedef struct io_scan_list {
CALLBACK callback;
struct scan_list scan_list;
scan_list scan_list;
struct io_scan_list *next;
};
}io_scan_list;
static io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
static struct io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
/* PERIODIC SCANNER */
static int nPeriodic=0;
static scan_list **papPeriodic; /* pointer to array of pointers*/
static int *periodicTaskId; /*array of integers after allocation*/
/* Private routines */
static void onceTask(void);
static void initOnce(void);
static void periodicTask(struct scan_list *psl);
static void periodicTask(scan_list *psl);
static void initPeriodic(void);
static void spawnPeriodic(int ind);
static void wdPeriodic(long ind);
static void eventTask(void);
static void initEvent(void);
static void spawnEvent(void);
static void wdEvent(void);
static void ioeventCallback(struct io_scan_list *piosl);
static void printList(struct scan_list *psl,char *message);
static void scanList(struct scan_list *psl);
static void eventCallback(event_scan_list *pevent_scan_list);
static void ioeventCallback(io_scan_list *piosl);
static void printList(scan_list *psl,char *message);
static void scanList(scan_list *psl);
static void buildScanLists(void);
static void addToList(struct dbCommon *precord,struct scan_list *psl);
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl);
static void addToList(struct dbCommon *precord,scan_list *psl);
static void deleteFromList(struct dbCommon *precord,scan_list *psl);
long scanInit()
{
@@ -143,38 +142,13 @@ long scanInit()
initEvent();
buildScanLists();
for (i=0;i<nPeriodic; i++) spawnPeriodic(i);
spawnEvent();
return(0);
}
void post_event(int event)
{
unsigned char evnt;
static int newOverflow=TRUE;
if (!interruptAccept) return; /* not awake yet */
if(event<0 || event>=MAX_EVENTS) {
errMessage(-1,"illegal event passed to post_event");
return;
}
evnt = (unsigned)event;
/*multiple writers can exist. Thus if evnt is ever changed to use*/
/*something bigger than a character interrupts will have to be blocked*/
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))
!=sizeof(unsigned char)) {
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
newOverflow = FALSE;
} else {
newOverflow = TRUE;
}
semGive(eventSem);
}
void scanAdd(struct dbCommon *precord)
{
short scan;
struct scan_list *psl;
scan_list *psl;
/* get the list on which this record belongs */
scan = precord->scan;
@@ -183,7 +157,9 @@ void scanAdd(struct dbCommon *precord)
recGblRecordError(-1,(void *)precord,
"scanAdd detected illegal SCAN value");
}else if(scan==SCAN_EVENT) {
unsigned char evnt;
unsigned char evnt;
int priority;
event_scan_list *pevent_scan_list;
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
recGblRecordError(S_db_badField,(void *)precord,
@@ -192,16 +168,25 @@ void scanAdd(struct dbCommon *precord)
return;
}
evnt = (signed)precord->evnt;
psl = papEvent[evnt];
if(psl==NULL) {
psl = dbCalloc(1,sizeof(struct scan_list));
papEvent[precord->evnt] = psl;
FASTLOCKINIT(&psl->lock);
ellInit(&psl->list);
priority = precord->prio;
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1,(void *)precord,
"scanAdd: illegal prio field");
precord->scan = SCAN_PASSIVE;
return;
}
pevent_scan_list = pevent_list[priority][evnt];
if(!pevent_scan_list ) {
pevent_scan_list = dbCalloc(1,sizeof(event_scan_list));
pevent_list[priority][evnt] = pevent_scan_list;
pevent_scan_list->callback.callback = eventCallback;
pevent_scan_list->callback.priority = priority;
ellInit(&pevent_scan_list->scan_list.list);
}
psl = &pevent_scan_list->scan_list;
addToList(precord,psl);
} else if(scan==SCAN_IO_EVENT) {
struct io_scan_list *piosl=NULL;
io_scan_list *piosl=NULL;
int priority;
DEVSUPFUN get_ioint_info;
@@ -250,7 +235,7 @@ void scanAdd(struct dbCommon *precord)
void scanDelete(struct dbCommon *precord)
{
short scan;
struct scan_list *psl;
scan_list *psl;
/* get the list on which this record belongs */
scan = precord->scan;
@@ -259,22 +244,33 @@ void scanDelete(struct dbCommon *precord)
recGblRecordError(-1,(void *)precord,
"scanDelete detected illegal SCAN value");
}else if(scan==SCAN_EVENT) {
unsigned char evnt;
unsigned char evnt;
int priority;
event_scan_list *pevent_scan_list;
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
recGblRecordError(S_db_badField,(void *)precord,
"scanDelete detected illegal EVNT value");
"scanAdd detected illegal EVNT value");
precord->scan = SCAN_PASSIVE;
return;
}
evnt = (signed)precord->evnt;
psl = papEvent[evnt];
if(psl==NULL)
priority = precord->prio;
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1,(void *)precord,
"scanAdd: illegal prio field");
precord->scan = SCAN_PASSIVE;
return;
}
pevent_scan_list = pevent_list[priority][evnt];
if(pevent_scan_list) psl = &pevent_scan_list->scan_list;
if(!pevent_scan_list || !psl)
recGblRecordError(-1,(void *)precord,
"scanDelete for bad evnt");
else
else
deleteFromList(precord,psl);
} else if(scan==SCAN_IO_EVENT) {
struct io_scan_list *piosl=NULL;
io_scan_list *piosl=NULL;
int priority;
DEVSUPFUN get_ioint_info;
@@ -315,7 +311,7 @@ void scanDelete(struct dbCommon *precord)
int scanppl() /*print periodic list*/
{
struct scan_list *psl;
scan_list *psl;
char message[80];
double period;
int i;
@@ -325,7 +321,7 @@ int scanppl() /*print periodic list*/
if(psl==NULL) continue;
period = psl->ticks;
period /= vxTicksPerSecond;
sprintf(message,"Scan Period= %f seconds\n",period);
sprintf(message,"Scan Period= %f seconds ",period);
printList(psl,message);
}
return(0);
@@ -333,22 +329,25 @@ int scanppl() /*print periodic list*/
int scanpel() /*print event list */
{
struct scan_list *psl;
char message[80];
int i;
char message[80];
int priority,evnt;
event_scan_list *pevent_scan_list;
for (i=0; i<MAX_EVENTS; i++) {
psl = papEvent[i];
if(psl==NULL) continue;
sprintf(message,"Event %d\n",i);
printList(psl,message);
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
pevent_scan_list = pevent_list[priority][evnt];
if(!pevent_scan_list) continue;
if(ellCount(&pevent_scan_list->scan_list) ==0) continue;
sprintf(message,"Event %d Priority %s",evnt,priorityName[priority]);
printList(&pevent_scan_list->scan_list,message);
}
}
return(0);
}
int scanpiol() /* print io_event list */
{
struct io_scan_list *piosl;
io_scan_list *piosl;
int priority;
char message[80];
@@ -364,14 +363,50 @@ int scanpiol() /* print io_event list */
return(0);
}
static void eventCallback(event_scan_list *pevent_scan_list)
{
scanList(&pevent_scan_list->scan_list);
}
static void initEvent(void)
{
int evnt,priority;
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
pevent_list[priority][evnt] = NULL;
}
}
}
void post_event(int event)
{
unsigned char evnt;
int priority;
event_scan_list *pevent_scan_list;
if (!interruptAccept) return; /* not awake yet */
if(event<0 || event>=MAX_EVENTS) {
errMessage(-1,"illegal event passed to post_event");
return;
}
evnt = (unsigned)event;
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
pevent_scan_list = pevent_list[priority][evnt];
if(!pevent_scan_list) continue;
if(ellCount(&pevent_scan_list->scan_list) >0)
callbackRequest((void *)pevent_scan_list);
}
}
void scanIoInit(IOSCANPVT *ppioscanpvt)
{
struct io_scan_list *piosl;
io_scan_list *piosl;
int priority;
/* allocate an array of io_scan_lists. One for each priority */
/* IOSCANPVT will hold the address of this array of structures */
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(struct io_scan_list));
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(io_scan_list));
for(priority=0, piosl=*ppioscanpvt;
priority<NUM_CALLBACK_PRIORITIES; priority++, piosl++){
piosl->callback.callback = ioeventCallback;
@@ -387,7 +422,7 @@ void scanIoInit(IOSCANPVT *ppioscanpvt)
void scanIoRequest(IOSCANPVT pioscanpvt)
{
struct io_scan_list *piosl;
io_scan_list *piosl;
int priority;
if(!interruptAccept) return;
@@ -447,7 +482,7 @@ static void initOnce(void)
taskwdInsert(onceTaskId,NULL,0L);
}
static void periodicTask(struct scan_list *psl)
static void periodicTask(scan_list *psl)
{
unsigned long start_time,end_time;
@@ -468,7 +503,7 @@ static void periodicTask(struct scan_list *psl)
static void initPeriodic()
{
dbMenu *pmenu;
struct scan_list *psl;
scan_list *psl;
float temp;
int i;
@@ -478,10 +513,10 @@ static void initPeriodic()
return;
}
nPeriodic = pmenu->nChoice - SCAN_1ST_PERIODIC;
papPeriodic = dbCalloc(nPeriodic,sizeof(struct scan_list*));
papPeriodic = dbCalloc(nPeriodic,sizeof(scan_list*));
periodicTaskId = dbCalloc(nPeriodic,sizeof(int));
for(i=0; i<nPeriodic; i++) {
psl = dbCalloc(1,sizeof(struct scan_list));
psl = dbCalloc(1,sizeof(scan_list));
papPeriodic[i] = psl;
FASTLOCKINIT(&psl->lock);
ellInit(&psl->list);
@@ -492,7 +527,7 @@ static void initPeriodic()
static void spawnPeriodic(int ind)
{
struct scan_list *psl;
scan_list *psl;
char taskName[20];
psl = papPeriodic[ind];
@@ -506,7 +541,7 @@ static void spawnPeriodic(int ind)
static void wdPeriodic(long ind)
{
struct scan_list *psl;
scan_list *psl;
if(!scanRestart)return;
psl = papPeriodic[ind];
@@ -516,83 +551,20 @@ static void wdPeriodic(long ind)
spawnPeriodic(ind);
}
static void eventTask(void)
static void ioeventCallback(io_scan_list *piosl)
{
unsigned char event;
struct scan_list *psl;
while(TRUE) {
if(semTake(eventSem,WAIT_FOREVER)!=OK)
errMessage(0,"semTake returned error in eventTask");
while (rngNBytes(eventQ)>=sizeof(unsigned char)){
if(rngBufGet(eventQ,(void *)&event,sizeof(unsigned char))!=sizeof(unsigned char))
errMessage(0,"rngBufGet returned error in eventTask");
if(event>MAX_EVENTS-1) {
errMessage(-1,"eventTask received an illegal event");
continue;
}
if(papEvent[event]==NULL) continue;
psl = papEvent[event];
if(psl) scanList(psl);
}
}
}
static void initEvent(void)
{
int i;
for(i=0; i<MAX_EVENTS; i++) papEvent[i] = 0;
eventQ = rngCreate(sizeof(unsigned char) * EVENT_QUEUE_SIZE);
if(eventQ==NULL) {
errMessage(0,"initEvent failed");
exit(1);
}
if((eventSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
errMessage(0,"semBcreate failed in initEvent");
}
static void spawnEvent(void)
{
eventTaskId = taskSpawn(EVENTSCAN_NAME,EVENTSCAN_PRI,EVENTSCAN_OPT,
EVENTSCAN_STACK,(FUNCPTR)eventTask,
0,0,0,0,0,0,0,0,0,0);
taskwdInsert(eventTaskId,wdEvent,0L);
}
static void wdEvent(void)
{
int i;
struct scan_list *psl;
if(!scanRestart) return;
taskwdRemove(eventTaskId);
if(semFlush(eventSem)!=OK)
errMessage(0,"semFlush failed while restarting eventTask");
rngFlush(eventQ);
for (i=0; i<MAX_EVENTS; i++) {
psl = papEvent[i];
if(psl==NULL) continue;
FASTUNLOCK(&psl->lock);
}
spawnEvent();
}
static void ioeventCallback(struct io_scan_list *piosl)
{
struct scan_list *psl=&piosl->scan_list;
scan_list *psl=&piosl->scan_list;
scanList(psl);
}
static void printList(struct scan_list *psl,char *message)
static void printList(scan_list *psl,char *message)
{
struct scan_element *pse;
scan_element *pse;
FASTLOCK(&psl->lock);
pse = (struct scan_element *)ellFirst(&psl->list);
pse = (scan_element *)ellFirst(&psl->list);
FASTUNLOCK(&psl->lock);
if(pse==NULL) return;
printf("%s\n",message);
@@ -604,23 +576,23 @@ static void printList(struct scan_list *psl,char *message)
printf("Returning because list changed while processing.");
return;
}
pse = (struct scan_element *)ellNext((void *)pse);
pse = (scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
}
}
static void scanList(struct scan_list *psl)
static void scanList(scan_list *psl)
{
/*In reading this code remember that the call to dbProcess can result*/
/*in the SCAN field being changed in an arbitrary number of records */
struct scan_element *pse,*prev,*next;
scan_element *pse,*prev,*next;
FASTLOCK(&psl->lock);
psl->modified = FALSE;
pse = (struct scan_element *)ellFirst(&psl->list);
pse = (scan_element *)ellFirst(&psl->list);
prev = NULL;
next = (struct scan_element *)ellNext((void *)pse);
next = (scan_element *)ellNext((void *)pse);
FASTUNLOCK(&psl->lock);
while(pse!=NULL) {
struct dbCommon *precord = pse->precord;
@@ -631,27 +603,27 @@ static void scanList(struct scan_list *psl)
FASTLOCK(&psl->lock);
if(!psl->modified) {
prev = pse;
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
pse = (scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
} else if (pse->pscan_list==psl) {
/*This scan element is still in same scan list*/
prev = pse;
pse = (struct scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
pse = (scan_element *)ellNext((void *)pse);
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else if (prev!=NULL && prev->pscan_list==psl) {
/*Previous scan element is still in same scan list*/
pse = (struct scan_element *)ellNext((void *)prev);
pse = (scan_element *)ellNext((void *)prev);
if(pse!=NULL) {
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
prev = (scan_element *)ellPrevious((void *)pse);
next = (scan_element *)ellNext((void *)pse);
}
psl->modified = FALSE;
} else if (next!=NULL && next->pscan_list==psl) {
/*Next scan element is still in same scan list*/
pse = next;
prev = (struct scan_element *)ellPrevious((void *)pse);
next = (struct scan_element *)ellNext((void *)pse);
prev = (scan_element *)ellPrevious((void *)pse);
next = (scan_element *)ellNext((void *)pse);
psl->modified = FALSE;
} else {
/*Too many changes. Just wait till next period*/
@@ -681,26 +653,26 @@ static void buildScanLists(void)
}
}
static void addToList(struct dbCommon *precord,struct scan_list *psl)
static void addToList(struct dbCommon *precord,scan_list *psl)
{
struct scan_element *pse,*ptemp;
scan_element *pse,*ptemp;
FASTLOCK(&psl->lock);
pse = (struct scan_element *)(precord->spvt);
pse = (scan_element *)(precord->spvt);
if(pse==NULL) {
pse = dbCalloc(1,sizeof(struct scan_element));
pse = dbCalloc(1,sizeof(scan_element));
precord->spvt = (void *)pse;
pse->precord = precord;
}
pse ->pscan_list = psl;
ptemp = (struct scan_element *)ellFirst(&psl->list);
ptemp = (scan_element *)ellFirst(&psl->list);
while(ptemp!=NULL) {
if(ptemp->precord->phas>precord->phas) {
ellInsert(&psl->list,
ellPrevious((void *)ptemp),(void *)pse);
break;
}
ptemp = (struct scan_element *)ellNext((void *)ptemp);
ptemp = (scan_element *)ellNext((void *)ptemp);
}
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
psl->modified = TRUE;
@@ -708,16 +680,16 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
return;
}
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl)
static void deleteFromList(struct dbCommon *precord,scan_list *psl)
{
struct scan_element *pse;
scan_element *pse;
FASTLOCK(&psl->lock);
if(precord->spvt==NULL) {
FASTUNLOCK(&psl->lock);
return;
}
pse = (struct scan_element *)(precord->spvt);
pse = (scan_element *)(precord->spvt);
if(pse==NULL || pse->pscan_list!=psl) {
FASTUNLOCK(&psl->lock);
errMessage(-1,"deleteFromList failed");