From d2abc71527f69e08444e7e6f81e56cf23d74f273 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 27 Apr 2012 13:22:00 -0400 Subject: [PATCH] Add function to dbChannel.c to create a db_field_log copy of array/string data --- src/ioc/db/dbChannel.c | 43 +++++++++++++++++++++++++++++++ src/ioc/db/dbChannel.h | 2 ++ src/ioc/db/filters/ts.c | 56 +---------------------------------------- src/ioc/misc/iocInit.c | 2 ++ 4 files changed, 48 insertions(+), 55 deletions(-) diff --git a/src/ioc/db/dbChannel.c b/src/ioc/db/dbChannel.c index 07fd97c29..ec85da201 100644 --- a/src/ioc/db/dbChannel.c +++ b/src/ioc/db/dbChannel.c @@ -22,6 +22,7 @@ #include "dbBase.h" #include "dbEvent.h" #include "link.h" +#include #include "dbAccessDefs.h" #include "dbLock.h" #include "dbStaticLib.h" @@ -43,6 +44,16 @@ typedef struct parseContext { #define CALLIF(rtn) !rtn ? parse_stop : rtn +static void *dbchStringFreeList; + +void dbChannelInit (void) +{ + if (!dbchStringFreeList) { + freeListInitPvt(&dbchStringFreeList, + sizeof(epicsOldString), 128); + } +} + static void chf_value(parseContext *parser, parse_result *presult) { chFilter *filter = parser->filter; @@ -676,6 +687,38 @@ void dbChannelDelete(dbChannel *chan) free(chan); // FIXME: Use free-list } +static void freeArray(db_field_log *pfl) { + if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { + freeListFree(dbchStringFreeList, pfl->u.r.field); + } else { + free(pfl->u.r.field); + } +} + +void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan) +{ + void *p; + + if (!pfl->type == dbfl_type_rec) return; + + struct dbCommon *prec = dbChannelRecord(chan); + pfl->type = dbfl_type_ref; + pfl->stat = prec->stat; + pfl->sevr = prec->sevr; + pfl->time = prec->time; + pfl->field_type = chan->addr.field_type; + pfl->no_elements = chan->addr.no_elements; + pfl->field_size = chan->addr.field_size; + pfl->u.r.dtor = freeArray; + pfl->u.r.pvt = pvt; + if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { + p = freeListCalloc(dbchStringFreeList); + } else { + p = calloc(pfl->no_elements, pfl->field_size); + } + if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL); + pfl->u.r.field = p; +} /* FIXME: Do these belong in a different file? */ diff --git a/src/ioc/db/dbChannel.h b/src/ioc/db/dbChannel.h index 485600311..2e50185aa 100644 --- a/src/ioc/db/dbChannel.h +++ b/src/ioc/db/dbChannel.h @@ -137,6 +137,7 @@ struct chFilter { struct dbCommon; struct dbFldDes; +epicsShareFunc void dbChannelInit (void); epicsShareFunc long dbChannelTest(const char *name); epicsShareFunc dbChannel * dbChannelCreate(const char *name); epicsShareFunc long dbChannelOpen(dbChannel *chan); @@ -171,6 +172,7 @@ epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, voi epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn); epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn); epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len); +epicsShareFunc void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan); #ifdef __cplusplus } diff --git a/src/ioc/db/filters/ts.c b/src/ioc/db/filters/ts.c index af6149b7c..26c56bfb8 100644 --- a/src/ioc/db/filters/ts.c +++ b/src/ioc/db/filters/ts.c @@ -11,43 +11,10 @@ */ #include -#include #include -#include #include #include -#include -#include - -static short mapDBFToDBR[DBF_NTYPES] = { - /* DBF_STRING => */ DBR_STRING, - /* DBF_CHAR => */ DBR_CHAR, - /* DBF_UCHAR => */ DBR_UCHAR, - /* DBF_SHORT => */ DBR_SHORT, - /* DBF_USHORT => */ DBR_USHORT, - /* DBF_LONG => */ DBR_LONG, - /* DBF_ULONG => */ DBR_ULONG, - /* DBF_FLOAT => */ DBR_FLOAT, - /* DBF_DOUBLE => */ DBR_DOUBLE, - /* DBF_ENUM, => */ DBR_ENUM, - /* DBF_MENU, => */ DBR_ENUM, - /* DBF_DEVICE => */ DBR_ENUM, - /* DBF_INLINK => */ DBR_STRING, - /* DBF_OUTLINK => */ DBR_STRING, - /* DBF_FWDLINK => */ DBR_STRING, - /* DBF_NOACCESS => */ DBR_NOACCESS -}; - -static void *tsStringFreeList; - -void freeArray(db_field_log *pfl) { - if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { - freeListFree(tsStringFreeList, pfl->u.r.field); - } else { - free(pfl->u.r.field); - } -} static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) { epicsTimeStamp now; @@ -55,23 +22,7 @@ static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) { /* If string or array, must make a copy (to ensure coherence between time and data) */ if (pfl->type == dbfl_type_rec) { - void *p; - struct dbCommon *prec = dbChannelRecord(chan); - pfl->type = dbfl_type_ref; - pfl->stat = prec->stat; - pfl->sevr = prec->sevr; - pfl->field_type = chan->addr.field_type; - pfl->no_elements = chan->addr.no_elements; - pfl->field_size = chan->addr.field_size; - pfl->u.r.dtor = freeArray; - pfl->u.r.pvt = pvt; - if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { - p = freeListCalloc(tsStringFreeList); - } else { - p = calloc(pfl->no_elements, pfl->field_size); - } - if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL); - pfl->u.r.field = p; + dbChannelMakeArrayCopy(pvt, pfl, chan); } pfl->time = now; @@ -112,11 +63,6 @@ static void tsInitialize(void) if(!firstTime) return; firstTime = 0; - if (!tsStringFreeList) { - freeListInitPvt(&tsStringFreeList, - sizeof(epicsOldString), 64); - } - chfPluginRegister("ts", &tsPif, NULL); } diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index f4e3b7e9e..18b0c6cd5 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -58,6 +58,7 @@ #include "initHooks.h" #include "epicsExit.h" #include "epicsSignal.h" +#include "dbChannel.h" #define epicsExportSharedSymbols #include "epicsRelease.h" @@ -460,6 +461,7 @@ static void doInitRecord1(dbRecordType *pdbRecordType, dbCommon *precord, static void initDatabase(void) { + dbChannelInit(); iterateRecords(doInitRecord0, NULL); iterateRecords(doResolveLinks, NULL); iterateRecords(doInitRecord1, NULL);