From e6b5aad8905e5c90b50e8dd7887a54518d7fba68 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Mon, 24 May 2010 08:09:39 -0700 Subject: [PATCH 1/9] Changed soft events from numbers to strings. --- src/db/dbCommon.dbd | 5 +- src/db/dbIocRegister.c | 4 +- src/db/dbScan.c | 103 +++++++++++++++++++++----------------- src/db/dbScan.h | 11 +++- src/rec/calcoutRecord.c | 18 +++---- src/rec/calcoutRecord.dbd | 2 +- src/rec/eventRecord.c | 10 ++-- src/rec/eventRecord.dbd | 8 +-- 8 files changed, 87 insertions(+), 74 deletions(-) diff --git a/src/db/dbCommon.dbd b/src/db/dbCommon.dbd index eb8e7bf35..051f690b8 100644 --- a/src/db/dbCommon.dbd +++ b/src/db/dbCommon.dbd @@ -43,10 +43,11 @@ special(SPC_SCAN) interest(1) } - field(EVNT,DBF_SHORT) { - prompt("Event Number") + field(EVNT,DBF_STRING) { + prompt("Event Name") promptgroup(GUI_SCAN) special(SPC_SCAN) + size(41) interest(1) } field(TSE,DBF_SHORT) { diff --git a/src/db/dbIocRegister.c b/src/db/dbIocRegister.c index a82337f03..c64738bbd 100644 --- a/src/db/dbIocRegister.c +++ b/src/db/dbIocRegister.c @@ -266,11 +266,11 @@ static void scanpplCallFunc(const iocshArgBuf *args) { scanppl(args[0].dval);} /* scanpel */ -static const iocshArg scanpelArg0 = { "event number",iocshArgInt}; +static const iocshArg scanpelArg0 = { "event name",iocshArgString}; static const iocshArg * const scanpelArgs[1] = {&scanpelArg0}; static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs}; static void scanpelCallFunc(const iocshArgBuf *args) -{ scanpel(args[0].ival);} +{ scanpel(args[0].sval);} /* scanpiol */ static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0}; diff --git a/src/db/dbScan.c b/src/db/dbScan.c index 5a372d6a9..b6f179660 100644 --- a/src/db/dbScan.c +++ b/src/db/dbScan.c @@ -101,12 +101,13 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = { /* EVENT */ -#define MAX_EVENTS 256 typedef struct event_scan_list { CALLBACK callback; scan_list scan_list; + char event_name[MAX_STRING_SIZE]; + struct event_scan_list *next; } event_scan_list; -static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS]; +static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES]; /* IO_EVENT*/ @@ -204,12 +205,12 @@ void scanAdd(struct dbCommon *precord) recGblRecordError(-1, (void *)precord, "scanAdd detected illegal SCAN value"); } else if (scan == menuScanEvent) { - int evnt; + char* evnt; int prio; - event_scan_list *pesl; + event_scan_list **ppesl; evnt = precord->evnt; - if (evnt < 0 || evnt >= MAX_EVENTS) { + if (*evnt == 0) { recGblRecordError(S_db_badField, (void *)precord, "scanAdd detected illegal EVNT value"); precord->scan = menuScanPassive; @@ -222,17 +223,20 @@ void scanAdd(struct dbCommon *precord) precord->scan = menuScanPassive; return; } - pesl = pevent_list[prio][evnt]; - if (pesl == NULL) { - pesl = dbCalloc(1, sizeof(event_scan_list)); - pevent_list[prio][evnt] = pesl; - pesl->scan_list.lock = epicsMutexMustCreate(); - callbackSetCallback(eventCallback, &pesl->callback); - callbackSetPriority(prio, &pesl->callback); - callbackSetUser(pesl, &pesl->callback); - ellInit(&pesl->scan_list.list); + for (ppesl = &pevent_list[prio]; *ppesl; ppesl=&(*ppesl)->next) { + if (strcmp((*ppesl)->event_name, evnt) == 0) break; } - addToList(precord, &pesl->scan_list); + + if (*ppesl == NULL) { + *ppesl = dbCalloc(1, sizeof(event_scan_list)); + strcpy((*ppesl)->event_name, evnt); + (*ppesl)->scan_list.lock = epicsMutexMustCreate(); + callbackSetCallback(eventCallback, &(*ppesl)->callback); + callbackSetPriority(prio, &(*ppesl)->callback); + callbackSetUser(*ppesl, &(*ppesl)->callback); + ellInit(&(*ppesl)->scan_list.list); + } + addToList(precord, &(*ppesl)->scan_list); } else if (scan == menuScanI_O_Intr) { io_scan_list *piosl = NULL; int prio; @@ -287,13 +291,13 @@ void scanDelete(struct dbCommon *precord) recGblRecordError(-1, (void *)precord, "scanDelete detected illegal SCAN value"); } else if (scan == menuScanEvent) { - int evnt; + char* evnt; int prio; event_scan_list *pesl; scan_list *psl = 0; evnt = precord->evnt; - if (evnt < 0 || evnt >= MAX_EVENTS) { + if (*evnt == 0) { recGblRecordError(S_db_badField, (void *)precord, "scanAdd detected illegal EVNT value"); precord->scan = menuScanPassive; @@ -306,7 +310,9 @@ void scanDelete(struct dbCommon *precord) precord->scan = menuScanPassive; return; } - pesl = pevent_list[prio][evnt]; + for (pesl = pevent_list[prio]; pesl; pesl=pesl->next) { + if (strcmp(pesl->event_name, evnt) == 0) break; + } if (pesl) psl = &pesl->scan_list; if (!pesl || !psl) recGblRecordError(-1, (void *)precord, @@ -372,21 +378,19 @@ int scanppl(double period) /* print periodic list */ return 0; } -int scanpel(int event_number) /* print event list */ +int scanpel(char* evnt) /* print event list */ { char message[80]; - int prio, evnt; + int prio; event_scan_list *pesl; - - for (evnt = 0; evnt < MAX_EVENTS; evnt++) { - if (event_number && evntevent_number) break; - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - pesl = pevent_list[prio][evnt]; - if (!pesl) continue; - if (ellCount(&pesl->scan_list.list) == 0) continue; - sprintf(message, "Event %d Priority %s", evnt, priorityName[prio]); - printList(&pesl->scan_list, message); + + for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { + for (pesl = pevent_list[prio]; pesl; pesl = pesl->next) { + if (evnt || strcmp(pesl->event_name, evnt) == 0) { + if (ellCount(&pesl->scan_list.list) == 0) continue; + sprintf(message, "Event \"%s\" Priority %s", evnt, priorityName[prio]); + printList(&pesl->scan_list, message); + } } } return 0; @@ -420,31 +424,36 @@ static void eventCallback(CALLBACK *pcallback) static void initEvent(void) { - int evnt, prio; + int prio; for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - for (evnt = 0; evnt < MAX_EVENTS; evnt++) { - pevent_list[prio][evnt] = NULL; + pevent_list[prio] = NULL; + } +} + +void post_named_event(char* evnt) +{ + int prio; + event_scan_list *pesl; + + if (scanCtl != ctlRun) return; + if (!evnt || *evnt == 0) return; + for (prio=0; prionext) { + if (strcmp(pesl->event_name, evnt) == 0) { + if (ellCount(&pesl->scan_list.list) >0) + callbackRequest((void *)pesl); + } } } } void post_event(int event) { - int prio; - event_scan_list *pesl; - - if (scanCtl != ctlRun) return; - if (event < 0 || event >= MAX_EVENTS) { - errMessage(-1, "illegal event passed to post_event"); - return; - } - for (prio=0; prioscan_list.list) >0) - callbackRequest((void *)pesl); - } + char event_name[10]; + + sprintf(event_name, "%i", event); + post_named_event(event_name); } void scanIoInit(IOSCANPVT *ppioscanpvt) diff --git a/src/db/dbScan.h b/src/db/dbScan.h index 717bae8ba..8b9837fea 100644 --- a/src/db/dbScan.h +++ b/src/db/dbScan.h @@ -32,6 +32,11 @@ extern "C" { #define MAX_PHASE SHRT_MAX #define MIN_PHASE SHRT_MIN + +#ifndef __GNUC__ +#define __attribute(dummy) +#endif + /*definitions for I/O Interrupt Scanning */ struct io_scan_list; @@ -43,7 +48,9 @@ epicsShareFunc long scanInit(void); epicsShareFunc void scanRun(void); epicsShareFunc void scanPause(void); -epicsShareFunc void post_event(int event); +epicsShareFunc void post_event(int event) __attribute__ ((deprecated)) + __attribute__ ((warning ("use post_named_event instead"))); +epicsShareFunc void post_named_event(char* event); epicsShareFunc void scanAdd(struct dbCommon *); epicsShareFunc void scanDelete(struct dbCommon *); epicsShareFunc double scanPeriod(int scan); @@ -54,7 +61,7 @@ epicsShareFunc int scanOnceSetQueueSize(int size); epicsShareFunc int scanppl(double rate); /*print event lists*/ -epicsShareFunc int scanpel(int event_number); +epicsShareFunc int scanpel(char *event_name); /*print io_event list*/ epicsShareFunc int scanpiol(void); diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c index f49c699d8..c8ee0069d 100644 --- a/src/rec/calcoutRecord.c +++ b/src/rec/calcoutRecord.c @@ -539,27 +539,21 @@ static void execOutput(calcoutRecord *prec) if (prec->nsev < INVALID_ALARM ) { /* Output the value */ status = writeValue(prec); - /* post event if output event != 0 */ - if (prec->oevt > 0) { - post_event((int)prec->oevt); - } + /* post output event if set */ + post_named_event(prec->oevt); } else switch (prec->ivoa) { case menuIvoaContinue_normally: status = writeValue(prec); - /* post event if output event != 0 */ - if (prec->oevt > 0) { - post_event((int)prec->oevt); - } + /* post output event if set */ + post_named_event(prec->oevt); break; case menuIvoaDon_t_drive_outputs: break; case menuIvoaSet_output_to_IVOV: prec->oval = prec->ivov; status = writeValue(prec); - /* post event if output event != 0 */ - if (prec->oevt > 0) { - post_event((int)prec->oevt); - } + /* post output event if set */ + post_named_event(prec->oevt); break; default: status = -1; diff --git a/src/rec/calcoutRecord.dbd b/src/rec/calcoutRecord.dbd index c7632ef12..99837ff4c 100644 --- a/src/rec/calcoutRecord.dbd +++ b/src/rec/calcoutRecord.dbd @@ -255,7 +255,7 @@ recordtype(calcout) { prompt("OCAL Valid") interest(1) } - field(OEVT,DBF_USHORT) { + field(OEVT,DBF_STRING) { prompt("Event To Issue") promptgroup(GUI_CLOCK) asl(ASL0) diff --git a/src/rec/eventRecord.c b/src/rec/eventRecord.c index 4785e78f3..9ba509857 100644 --- a/src/rec/eventRecord.c +++ b/src/rec/eventRecord.c @@ -103,7 +103,7 @@ static long init_record(eventRecord *prec, int pass) } if (prec->siol.type == CONSTANT) { - recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval); + recGblInitConstantLink(&prec->siol,DBF_STRING,&prec->sval); } if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) ) @@ -123,7 +123,7 @@ static long process(eventRecord *prec) if ( !pact && prec->pact ) return(0); prec->pact = TRUE; - if(prec->val>0) post_event((int)prec->val); + post_named_event(prec->val); recGblGetTimeStamp(prec); @@ -140,7 +140,7 @@ static long process(eventRecord *prec) static long get_value(eventRecord *prec, struct valueDes *pvdes) { - pvdes->field_type = DBF_USHORT; + pvdes->field_type = DBF_STRING; pvdes->no_elements=1; pvdes->pvalue = (void *)(&prec->val); return(0); @@ -177,10 +177,10 @@ static long readValue(eventRecord *prec) return(status); } if (prec->simm == menuYesNoYES){ - status=dbGetLink(&(prec->siol),DBR_USHORT, + status=dbGetLink(&(prec->siol),DBR_STRING, &(prec->sval),0,0); if (status==0) { - prec->val=prec->sval; + strcpy(prec->val, prec->sval); prec->udf=FALSE; } } else { diff --git a/src/rec/eventRecord.dbd b/src/rec/eventRecord.dbd index f63355900..da60de56a 100644 --- a/src/rec/eventRecord.dbd +++ b/src/rec/eventRecord.dbd @@ -9,10 +9,11 @@ #************************************************************************* recordtype(event) { include "dbCommon.dbd" - field(VAL,DBF_USHORT) { - prompt("Event Number To Post") + field(VAL,DBF_STRING) { + prompt("Event Name To Post") promptgroup(GUI_INPUTS) asl(ASL0) + size(40) } field(INP,DBF_INLINK) { prompt("Input Specification") @@ -24,8 +25,9 @@ recordtype(event) { promptgroup(GUI_INPUTS) interest(1) } - field(SVAL,DBF_USHORT) { + field(SVAL,DBF_STRING) { prompt("Simulation Value") + size(40) } field(SIML,DBF_INLINK) { prompt("Sim Mode Location") From 3f6fd95ef894fb175bbc74f1631b23552613e2c8 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Mon, 24 May 2010 08:42:36 -0700 Subject: [PATCH 2/9] OEVT size was missing --- src/rec/calcoutRecord.dbd | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rec/calcoutRecord.dbd b/src/rec/calcoutRecord.dbd index 99837ff4c..539351d1f 100644 --- a/src/rec/calcoutRecord.dbd +++ b/src/rec/calcoutRecord.dbd @@ -259,6 +259,7 @@ recordtype(calcout) { prompt("Event To Issue") promptgroup(GUI_CLOCK) asl(ASL0) + size(40) } field(IVOA,DBF_MENU) { prompt("INVALID output action") From 21e96c5882d9a0cbe09e869e6be19d6777807a01 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 25 May 2010 03:40:49 -0700 Subject: [PATCH 3/9] string val field --- src/dev/softDev/devEventSoft.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dev/softDev/devEventSoft.c b/src/dev/softDev/devEventSoft.c index 8b1670720..ba69fdecc 100644 --- a/src/dev/softDev/devEventSoft.c +++ b/src/dev/softDev/devEventSoft.c @@ -51,7 +51,7 @@ static long init_record(eventRecord *prec) /* INP must be CONSTANT, PV_LINK, DB_LINK or CA_LINK*/ switch (prec->inp.type) { case CONSTANT: - if (recGblInitConstantLink(&prec->inp, DBF_USHORT, &prec->val)) + if (recGblInitConstantLink(&prec->inp, DBF_STRING, &prec->val)) prec->udf = FALSE; break; case PV_LINK: @@ -70,7 +70,7 @@ static long read_event(eventRecord *prec) { long status; - status = dbGetLink(&prec->inp, DBR_USHORT, &prec->val, 0, 0); + status = dbGetLink(&prec->inp, DBR_STRING, prec->val, 0, 0); if (!status) { prec->udf = FALSE; if (prec->tsel.type == CONSTANT && From 0a7720479520d9d1f42b428f11e4990b6db6f6d1 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 25 May 2010 03:41:18 -0700 Subject: [PATCH 4/9] stringlength and mutex issues fixed --- src/db/dbCommon.dbd | 2 +- src/db/dbScan.c | 93 +++++++++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/db/dbCommon.dbd b/src/db/dbCommon.dbd index 051f690b8..94128ca35 100644 --- a/src/db/dbCommon.dbd +++ b/src/db/dbCommon.dbd @@ -47,7 +47,7 @@ prompt("Event Name") promptgroup(GUI_SCAN) special(SPC_SCAN) - size(41) + size(40) interest(1) } field(TSE,DBF_SHORT) { diff --git a/src/db/dbScan.c b/src/db/dbScan.c index b6f179660..32740a53a 100644 --- a/src/db/dbScan.c +++ b/src/db/dbScan.c @@ -104,10 +104,11 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = { typedef struct event_scan_list { CALLBACK callback; scan_list scan_list; - char event_name[MAX_STRING_SIZE]; struct event_scan_list *next; + char event_name[MAX_STRING_SIZE]; } event_scan_list; static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES]; +static epicsMutexId event_list_lock[NUM_CALLBACK_PRIORITIES]; /* IO_EVENT*/ @@ -207,36 +208,45 @@ void scanAdd(struct dbCommon *precord) } else if (scan == menuScanEvent) { char* evnt; int prio; - event_scan_list **ppesl; + event_scan_list *pesl; evnt = precord->evnt; if (*evnt == 0) { recGblRecordError(S_db_badField, (void *)precord, - "scanAdd detected illegal EVNT value"); - precord->scan = menuScanPassive; + "scanAdd: illegal empty EVNT value"); + /*precord->scan = menuScanPassive;*/ + return; + } + if (strlen(evnt) >= MAX_STRING_SIZE) { + recGblRecordError(S_db_badField, (void *)precord, + "scanAdd: too long EVNT value"); + /*precord->scan = menuScanPassive;*/ return; } prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, "scanAdd: illegal prio field"); - precord->scan = menuScanPassive; + /*precord->scan = menuScanPassive;*/ return; } - for (ppesl = &pevent_list[prio]; *ppesl; ppesl=&(*ppesl)->next) { - if (strcmp((*ppesl)->event_name, evnt) == 0) break; + epicsMutexMustLock(event_list_lock[prio]); + for (pesl = pevent_list[prio]; pesl; pesl=pesl->next) { + if (strcmp(pesl->event_name, evnt) == 0) break; } - - if (*ppesl == NULL) { - *ppesl = dbCalloc(1, sizeof(event_scan_list)); - strcpy((*ppesl)->event_name, evnt); - (*ppesl)->scan_list.lock = epicsMutexMustCreate(); - callbackSetCallback(eventCallback, &(*ppesl)->callback); - callbackSetPriority(prio, &(*ppesl)->callback); - callbackSetUser(*ppesl, &(*ppesl)->callback); - ellInit(&(*ppesl)->scan_list.list); + if (pesl == NULL) { + pesl = dbCalloc(1, sizeof(event_scan_list)); + strcpy(pesl->event_name, evnt); + pesl->scan_list.lock = epicsMutexMustCreate(); + callbackSetCallback(eventCallback, &pesl->callback); + callbackSetPriority(prio, &pesl->callback); + callbackSetUser(pesl, &pesl->callback); + ellInit(&pesl->scan_list.list); + pesl->next=pevent_list[prio]; + pevent_list[prio]=pesl; } - addToList(precord, &(*ppesl)->scan_list); + epicsMutexUnlock(event_list_lock[prio]); + addToList(precord, &pesl->scan_list); } else if (scan == menuScanI_O_Intr) { io_scan_list *piosl = NULL; int prio; @@ -297,27 +307,19 @@ void scanDelete(struct dbCommon *precord) scan_list *psl = 0; evnt = precord->evnt; - if (*evnt == 0) { - recGblRecordError(S_db_badField, (void *)precord, - "scanAdd detected illegal EVNT value"); - precord->scan = menuScanPassive; - return; - } prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, - "scanAdd: illegal prio field"); - precord->scan = menuScanPassive; + "scanDelete detected illegal PRIO field"); return; } - for (pesl = pevent_list[prio]; pesl; pesl=pesl->next) { - if (strcmp(pesl->event_name, evnt) == 0) break; + epicsMutexMustLock(event_list_lock[prio]); + pesl = pevent_list[prio]; + epicsMutexUnlock(event_list_lock[prio]); + for (; pesl; pesl=pesl->next) { + if (strcmp(pesl->event_name, evnt) == 0) break; } - if (pesl) psl = &pesl->scan_list; - if (!pesl || !psl) - recGblRecordError(-1, (void *)precord, - "scanDelete for bad evnt"); - else + if (pesl && (psl = &pesl->scan_list)) deleteFromList(precord, psl); } else if (scan == menuScanI_O_Intr) { io_scan_list *piosl=NULL; @@ -385,11 +387,14 @@ int scanpel(char* evnt) /* print event list */ event_scan_list *pesl; for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - for (pesl = pevent_list[prio]; pesl; pesl = pesl->next) { - if (evnt || strcmp(pesl->event_name, evnt) == 0) { - if (ellCount(&pesl->scan_list.list) == 0) continue; - sprintf(message, "Event \"%s\" Priority %s", evnt, priorityName[prio]); - printList(&pesl->scan_list, message); + epicsMutexMustLock(event_list_lock[prio]); + pesl = pevent_list[prio]; + epicsMutexUnlock(event_list_lock[prio]); + for (; pesl; pesl = pesl->next) { + if (!evnt || strcmp(pesl->event_name, evnt) == 0) { + if (ellCount(&pesl->scan_list.list) == 0) continue; + sprintf(message, "Event \"%s\" Priority %s", pesl->event_name, priorityName[prio]); + printList(&pesl->scan_list, message); } } } @@ -427,7 +432,8 @@ static void initEvent(void) int prio; for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - pevent_list[prio] = NULL; + pevent_list[prio] = NULL; + event_list_lock[prio] = epicsMutexMustCreate(); } } @@ -439,8 +445,11 @@ void post_named_event(char* evnt) if (scanCtl != ctlRun) return; if (!evnt || *evnt == 0) return; for (prio=0; prionext) { - if (strcmp(pesl->event_name, evnt) == 0) { + epicsMutexMustLock(event_list_lock[prio]); + pesl = pevent_list[prio]; + epicsMutexUnlock(event_list_lock[prio]); + for (; pesl; pesl=pesl->next) { + if (strcmp(pesl->event_name, evnt) == 0) { if (ellCount(&pesl->scan_list.list) >0) callbackRequest((void *)pesl); } @@ -450,10 +459,10 @@ void post_named_event(char* evnt) void post_event(int event) { - char event_name[10]; + char event_name[10]; sprintf(event_name, "%i", event); - post_named_event(event_name); + post_named_event(event_name); } void scanIoInit(IOSCANPVT *ppioscanpvt) From 037db16b0043068d868710a846ee3e71eabc682a Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Fri, 28 May 2010 03:04:09 -0700 Subject: [PATCH 5/9] release notes updated --- documentation/RELEASE_NOTES.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9b3ce378e..7efe63498 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -12,6 +12,10 @@

Changes between 3.14.11 and 3.14.12

+

Named Soft Events

+ +

Soft events can now be meaningful strings instead of numbers 1-255. +

Rewrite epicsThreadOnce()

Michael Davidsaver suggested a better implementation of epicsThreadOnce() From 0e818f6127f59d2b8933aab73910ec83b3bc641e Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Fri, 15 Oct 2010 02:02:48 +0200 Subject: [PATCH 6/9] use EPICS_DEPRECATED macro --- src/db/dbScan.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/db/dbScan.h b/src/db/dbScan.h index 8b9837fea..62e04c500 100644 --- a/src/db/dbScan.h +++ b/src/db/dbScan.h @@ -19,6 +19,7 @@ #include "menuScan.h" #include "shareLib.h" +#include "compilerDependencies.h" #ifdef __cplusplus extern "C" { @@ -32,11 +33,6 @@ extern "C" { #define MAX_PHASE SHRT_MAX #define MIN_PHASE SHRT_MIN - -#ifndef __GNUC__ -#define __attribute(dummy) -#endif - /*definitions for I/O Interrupt Scanning */ struct io_scan_list; @@ -48,8 +44,7 @@ epicsShareFunc long scanInit(void); epicsShareFunc void scanRun(void); epicsShareFunc void scanPause(void); -epicsShareFunc void post_event(int event) __attribute__ ((deprecated)) - __attribute__ ((warning ("use post_named_event instead"))); +epicsShareFunc void post_event(int event) EPICS_DEPRECATED; epicsShareFunc void post_named_event(char* event); epicsShareFunc void scanAdd(struct dbCommon *); epicsShareFunc void scanDelete(struct dbCommon *); From 0d8725857bf4ba66efce8f10e6ed2303ce9f5a16 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 27 Oct 2010 21:56:12 +0200 Subject: [PATCH 7/9] new approach to handle named events efficiently --- src/db/dbScan.c | 163 +++++++++++++++++---------------- src/db/dbScan.h | 4 +- src/dev/softDev/devEventSoft.c | 8 +- src/rec/calcoutRecord.c | 11 ++- src/rec/calcoutRecord.dbd | 8 ++ src/rec/eventRecord.c | 23 ++++- src/rec/eventRecord.dbd | 8 ++ 7 files changed, 136 insertions(+), 89 deletions(-) diff --git a/src/db/dbScan.c b/src/db/dbScan.c index 32740a53a..5ba5500a9 100644 --- a/src/db/dbScan.c +++ b/src/db/dbScan.c @@ -101,14 +101,13 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = { /* EVENT */ -typedef struct event_scan_list { - CALLBACK callback; - scan_list scan_list; - struct event_scan_list *next; +typedef struct event_list { + CALLBACK callback[NUM_CALLBACK_PRIORITIES]; + scan_list scan_list[NUM_CALLBACK_PRIORITIES]; + struct event_list *next; char event_name[MAX_STRING_SIZE]; -} event_scan_list; -static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES]; -static epicsMutexId event_list_lock[NUM_CALLBACK_PRIORITIES]; +} event_list; +static event_list * volatile pevent_list[256]; /* IO_EVENT*/ @@ -206,47 +205,24 @@ void scanAdd(struct dbCommon *precord) recGblRecordError(-1, (void *)precord, "scanAdd detected illegal SCAN value"); } else if (scan == menuScanEvent) { - char* evnt; + char* eventname; int prio; - event_scan_list *pesl; + event_list *pel; - evnt = precord->evnt; - if (*evnt == 0) { - recGblRecordError(S_db_badField, (void *)precord, - "scanAdd: illegal empty EVNT value"); - /*precord->scan = menuScanPassive;*/ - return; - } - if (strlen(evnt) >= MAX_STRING_SIZE) { + eventname = precord->evnt; + if (strlen(eventname) >= MAX_STRING_SIZE) { recGblRecordError(S_db_badField, (void *)precord, "scanAdd: too long EVNT value"); - /*precord->scan = menuScanPassive;*/ return; } prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, "scanAdd: illegal prio field"); - /*precord->scan = menuScanPassive;*/ return; } - epicsMutexMustLock(event_list_lock[prio]); - for (pesl = pevent_list[prio]; pesl; pesl=pesl->next) { - if (strcmp(pesl->event_name, evnt) == 0) break; - } - if (pesl == NULL) { - pesl = dbCalloc(1, sizeof(event_scan_list)); - strcpy(pesl->event_name, evnt); - pesl->scan_list.lock = epicsMutexMustCreate(); - callbackSetCallback(eventCallback, &pesl->callback); - callbackSetPriority(prio, &pesl->callback); - callbackSetUser(pesl, &pesl->callback); - ellInit(&pesl->scan_list.list); - pesl->next=pevent_list[prio]; - pevent_list[prio]=pesl; - } - epicsMutexUnlock(event_list_lock[prio]); - addToList(precord, &pesl->scan_list); + pel = eventNameToHandle(eventname); + if (pel) addToList(precord, &pel->scan_list[prio]); } else if (scan == menuScanI_O_Intr) { io_scan_list *piosl = NULL; int prio; @@ -301,25 +277,25 @@ void scanDelete(struct dbCommon *precord) recGblRecordError(-1, (void *)precord, "scanDelete detected illegal SCAN value"); } else if (scan == menuScanEvent) { - char* evnt; + char* eventname; int prio; - event_scan_list *pesl; + event_list *pel; scan_list *psl = 0; - evnt = precord->evnt; + eventname = precord->evnt; prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, "scanDelete detected illegal PRIO field"); return; } - epicsMutexMustLock(event_list_lock[prio]); - pesl = pevent_list[prio]; - epicsMutexUnlock(event_list_lock[prio]); - for (; pesl; pesl=pesl->next) { - if (strcmp(pesl->event_name, evnt) == 0) break; + do /* multitheading: make sure pel is consistent */ + pel = pevent_list[0]; + while (pel != pevent_list[0]); + for (; pel; pel=pel->next) { + if (strcmp(pel->event_name, eventname) == 0) break; } - if (pesl && (psl = &pesl->scan_list)) + if (pel && (psl = &pel->scan_list[prio])) deleteFromList(precord, psl); } else if (scan == menuScanI_O_Intr) { io_scan_list *piosl=NULL; @@ -380,21 +356,21 @@ int scanppl(double period) /* print periodic list */ return 0; } -int scanpel(char* evnt) /* print event list */ +int scanpel(char* eventname) /* print event list */ { char message[80]; int prio; - event_scan_list *pesl; + event_list *pel; - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - epicsMutexMustLock(event_list_lock[prio]); - pesl = pevent_list[prio]; - epicsMutexUnlock(event_list_lock[prio]); - for (; pesl; pesl = pesl->next) { - if (!evnt || strcmp(pesl->event_name, evnt) == 0) { - if (ellCount(&pesl->scan_list.list) == 0) continue; - sprintf(message, "Event \"%s\" Priority %s", pesl->event_name, priorityName[prio]); - printList(&pesl->scan_list, message); + do /* multitheading: make sure pel is consistent */ + pel = pevent_list[0]; + while (pel != pevent_list[0]); + for (; pel; pel = pel->next) { + if (!eventname || strcmp(pel->event_name, eventname) == 0) { + for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { + if (ellCount(&pel->scan_list[prio].list) == 0) continue; + sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]); + printList(&pel->scan_list[prio], message); } } } @@ -421,48 +397,73 @@ int scanpiol(void) /* print io_event list */ static void eventCallback(CALLBACK *pcallback) { - event_scan_list *pesl; + scan_list *psl; - callbackGetUser(pesl, pcallback); - scanList(&pesl->scan_list); + callbackGetUser(psl, pcallback); + scanList(psl); } static void initEvent(void) { - int prio; - - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - pevent_list[prio] = NULL; - event_list_lock[prio] = epicsMutexMustCreate(); - } } -void post_named_event(char* evnt) +event_list *eventNameToHandle(char *eventname) { int prio; - event_scan_list *pesl; + event_list *pel; + static epicsMutexId lock = NULL; - if (scanCtl != ctlRun) return; - if (!evnt || *evnt == 0) return; - for (prio=0; prionext) { - if (strcmp(pesl->event_name, evnt) == 0) { - if (ellCount(&pesl->scan_list.list) >0) - callbackRequest((void *)pesl); - } + if (!lock) lock = epicsMutexMustCreate(); + if (!eventname || eventname[0] == 0) return NULL; + epicsMutexMustLock(lock); + for (pel = pevent_list[0]; pel; pel=pel->next) { + if (strcmp(pel->event_name, eventname) == 0) break; + } + if (pel == NULL) { + pel = dbCalloc(1, sizeof(event_list)); + strcpy(pel->event_name, eventname); + for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { + callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]); + callbackSetPriority(prio, &pel->callback[prio]); + callbackSetCallback(eventCallback, &pel->callback[prio]); + pel->scan_list[prio].lock = epicsMutexMustCreate(); + ellInit(&pel->scan_list[prio].list); + } + pel->next=pevent_list[0]; + pevent_list[0]=pel; + { /* backward compatibility */ + char* p; + long e = strtol(eventname, &p, 0); + if (*p == 0 && e > 0 && e <= 255) + pevent_list[e]=pel; } } + epicsMutexUnlock(lock); + return pel; } +void postEvent(event_list *pel) +{ + int prio; + + if (scanCtl != ctlRun) return; + if (!pel) return; + for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { + if (ellCount(&pel->scan_list[prio].list) >0) + callbackRequest(&pel->callback[prio]); + } +} + +/* backward compatibility */ void post_event(int event) { - char event_name[10]; + event_list* pel; - sprintf(event_name, "%i", event); - post_named_event(event_name); + if (event <= 0 || event > 255) return; + do { /* multitheading: make sure pel is consistent */ + pel = pevent_list[event]; + } while (pel != pevent_list[event]); + postEvent(pel); } void scanIoInit(IOSCANPVT *ppioscanpvt) diff --git a/src/db/dbScan.h b/src/db/dbScan.h index 62e04c500..966849511 100644 --- a/src/db/dbScan.h +++ b/src/db/dbScan.h @@ -37,6 +37,7 @@ extern "C" { struct io_scan_list; typedef struct io_scan_list *IOSCANPVT; +typedef struct event_list *EVENTPVT; struct dbCommon; @@ -44,8 +45,9 @@ epicsShareFunc long scanInit(void); epicsShareFunc void scanRun(void); epicsShareFunc void scanPause(void); +epicsShareFunc EVENTPVT eventNameToHandle(char* event); +epicsShareFunc void postEvent(EVENTPVT epvt); epicsShareFunc void post_event(int event) EPICS_DEPRECATED; -epicsShareFunc void post_named_event(char* event); epicsShareFunc void scanAdd(struct dbCommon *); epicsShareFunc void scanDelete(struct dbCommon *); epicsShareFunc double scanPeriod(int scan); diff --git a/src/dev/softDev/devEventSoft.c b/src/dev/softDev/devEventSoft.c index ba69fdecc..bde80a452 100644 --- a/src/dev/softDev/devEventSoft.c +++ b/src/dev/softDev/devEventSoft.c @@ -69,9 +69,15 @@ static long init_record(eventRecord *prec) static long read_event(eventRecord *prec) { long status; + char newEvent[MAX_STRING_SIZE]; - status = dbGetLink(&prec->inp, DBR_STRING, prec->val, 0, 0); + if (prec->inp.type == CONSTANT) return 0; + status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0); if (!status) { + if (strcmp(newEvent, prec->val) != 0) { + strcpy(prec->val, newEvent); + prec->epvt = eventNameToHandle(prec->val); + } prec->udf = FALSE; if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c index c8ee0069d..3cbef9fe1 100644 --- a/src/rec/calcoutRecord.c +++ b/src/rec/calcoutRecord.c @@ -197,6 +197,8 @@ static long init_record(calcoutRecord *prec, int pass) callbackSetUser(prec, &prpvt->checkLinkCb); prpvt->cbScheduled = 0; + prec->epvt = eventNameToHandle(prec->oevt); + if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec); prec->pval = prec->val; prec->mlst = prec->val; @@ -357,6 +359,9 @@ static long special(DBADDR *paddr, int after) } db_post_events(prec, plinkValid, DBE_VALUE); return 0; + case(calcoutRecordOEVT): + prec->epvt = eventNameToHandle(prec->oevt); + return 0; default: recGblDbaddrError(S_db_badChoice, paddr, "calc: special"); return(S_db_badChoice); @@ -540,12 +545,12 @@ static void execOutput(calcoutRecord *prec) /* Output the value */ status = writeValue(prec); /* post output event if set */ - post_named_event(prec->oevt); + if (prec->epvt) postEvent(prec->epvt); } else switch (prec->ivoa) { case menuIvoaContinue_normally: status = writeValue(prec); /* post output event if set */ - post_named_event(prec->oevt); + if (prec->epvt) postEvent(prec->epvt); break; case menuIvoaDon_t_drive_outputs: break; @@ -553,7 +558,7 @@ static void execOutput(calcoutRecord *prec) prec->oval = prec->ivov; status = writeValue(prec); /* post output event if set */ - post_named_event(prec->oevt); + if (prec->epvt) postEvent(prec->epvt); break; default: status = -1; diff --git a/src/rec/calcoutRecord.dbd b/src/rec/calcoutRecord.dbd index 539351d1f..45779b22d 100644 --- a/src/rec/calcoutRecord.dbd +++ b/src/rec/calcoutRecord.dbd @@ -258,9 +258,17 @@ recordtype(calcout) { field(OEVT,DBF_STRING) { prompt("Event To Issue") promptgroup(GUI_CLOCK) + special(SPC_MOD) asl(ASL0) size(40) } + %#include "dbScan.h" + field(EPVT, DBF_NOACCESS) { + prompt("Event private") + special(SPC_NOMOD) + interest(4) + extra("EVENTPVT epvt") + } field(IVOA,DBF_MENU) { prompt("INVALID output action") promptgroup(GUI_OUTPUT) diff --git a/src/rec/eventRecord.c b/src/rec/eventRecord.c index 9ba509857..f9a278428 100644 --- a/src/rec/eventRecord.c +++ b/src/rec/eventRecord.c @@ -32,6 +32,7 @@ #include "errMdef.h" #include "recSup.h" #include "recGbl.h" +#include "special.h" #include "menuYesNo.h" #define GEN_SIZE_OFFSET #include "eventRecord.h" @@ -43,7 +44,7 @@ #define initialize NULL static long init_record(eventRecord *, int); static long process(eventRecord *); -#define special NULL +static long special(DBADDR *, int); static long get_value(eventRecord *, struct valueDes *); #define cvt_dbaddr NULL #define get_array_info NULL @@ -106,6 +107,8 @@ static long init_record(eventRecord *prec, int pass) recGblInitConstantLink(&prec->siol,DBF_STRING,&prec->sval); } + prec->epvt = eventNameToHandle(prec->val); + if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) ) status=(*pdset->init_record)(prec); return(status); @@ -123,7 +126,7 @@ static long process(eventRecord *prec) if ( !pact && prec->pact ) return(0); prec->pact = TRUE; - post_named_event(prec->val); + postEvent(prec->epvt); recGblGetTimeStamp(prec); @@ -137,7 +140,18 @@ static long process(eventRecord *prec) return(status); } + +static long special(DBADDR *paddr, int after) +{ + eventRecord *prec = (eventRecord *)paddr->precord; + + if (!after) return 0; + if (dbGetFieldIndex(paddr) == eventRecordVAL) { + prec->epvt = eventNameToHandle(prec->val); + } +} + static long get_value(eventRecord *prec, struct valueDes *pvdes) { pvdes->field_type = DBF_STRING; @@ -180,7 +194,10 @@ static long readValue(eventRecord *prec) status=dbGetLink(&(prec->siol),DBR_STRING, &(prec->sval),0,0); if (status==0) { - strcpy(prec->val, prec->sval); + if (strcmp(prec->sval, prec->val) != 0) { + strcpy(prec->val, prec->sval); + prec->epvt = eventNameToHandle(prec->val); + } prec->udf=FALSE; } } else { diff --git a/src/rec/eventRecord.dbd b/src/rec/eventRecord.dbd index da60de56a..f7bbb7ee7 100644 --- a/src/rec/eventRecord.dbd +++ b/src/rec/eventRecord.dbd @@ -12,9 +12,17 @@ recordtype(event) { field(VAL,DBF_STRING) { prompt("Event Name To Post") promptgroup(GUI_INPUTS) + special(SPC_MOD) asl(ASL0) size(40) } + %#include "dbScan.h" + field(EPVT, DBF_NOACCESS) { + prompt("Event private") + special(SPC_NOMOD) + interest(4) + extra("EVENTPVT epvt") + } field(INP,DBF_INLINK) { prompt("Input Specification") promptgroup(GUI_INPUTS) From 7e7d04576be39fa9ae2d5c4b893ff3f190910ba5 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 27 Oct 2010 22:19:33 +0200 Subject: [PATCH 8/9] bugfix: devEventSoft read_event with constant input and tse = epicsTimeEventDeviceTime did not read timestamp --- src/dev/softDev/devEventSoft.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dev/softDev/devEventSoft.c b/src/dev/softDev/devEventSoft.c index bde80a452..71b00587b 100644 --- a/src/dev/softDev/devEventSoft.c +++ b/src/dev/softDev/devEventSoft.c @@ -71,17 +71,18 @@ static long read_event(eventRecord *prec) long status; char newEvent[MAX_STRING_SIZE]; - if (prec->inp.type == CONSTANT) return 0; - status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0); - if (!status) { + if (prec->inp.type != CONSTANT) + { + status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0); + if (status) return status; if (strcmp(newEvent, prec->val) != 0) { strcpy(prec->val, newEvent); prec->epvt = eventNameToHandle(prec->val); } - prec->udf = FALSE; - if (prec->tsel.type == CONSTANT && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(&prec->inp, &prec->time); } - return status; + prec->udf = FALSE; + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + dbGetTimeStamp(&prec->inp, &prec->time); + return 0; } From c73efe7f39d1bf951509a9ea74e69d96809bf9a9 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 27 Oct 2010 22:49:16 +0200 Subject: [PATCH 9/9] typo in comment --- src/db/dbScan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/dbScan.c b/src/db/dbScan.c index 5ba5500a9..1720a5d85 100644 --- a/src/db/dbScan.c +++ b/src/db/dbScan.c @@ -289,7 +289,7 @@ void scanDelete(struct dbCommon *precord) "scanDelete detected illegal PRIO field"); return; } - do /* multitheading: make sure pel is consistent */ + do /* multithreading: make sure pel is consistent */ pel = pevent_list[0]; while (pel != pevent_list[0]); for (; pel; pel=pel->next) { @@ -362,7 +362,7 @@ int scanpel(char* eventname) /* print event list */ int prio; event_list *pel; - do /* multitheading: make sure pel is consistent */ + do /* multithreading: make sure pel is consistent */ pel = pevent_list[0]; while (pel != pevent_list[0]); for (; pel; pel = pel->next) { @@ -460,7 +460,7 @@ void post_event(int event) event_list* pel; if (event <= 0 || event > 255) return; - do { /* multitheading: make sure pel is consistent */ + do { /* multithreading: make sure pel is consistent */ pel = pevent_list[event]; } while (pel != pevent_list[event]); postEvent(pel);