I have re-structured the code a bit to make it less confusing. Also debug output is in. Tell me if you like it, then I will push it (without the debug code).
static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
long *pnRequest)
{
struct pv_link *ppv_link = &plink->value.pv_link;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
dbCommon *precord = plink->precord;
db_field_log *pfl = NULL;
long status;
struct timespec start, stop;
int path;
/* scan passive records if link is process passive */
if (ppv_link->pvlMask & pvlOptPP) {
status = dbScanPassive(precord, dbChannelRecord(chan));
if (status)
return status;
}
clock_gettime(CLOCK_MONOTONIC, &start);
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType)
{
/* shortcut: scalar with known conversion, no filter */
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
path = 1;
}
else if (dbChannelFinalElements(chan) == 1 && (!pnRequest || *pnRequest == 1)
&& dbChannelSpecial(chan) != SPC_DBADDR
&& dbChannelSpecial(chan) != SPC_ATTRIBUTE
&& ellCount(&chan->filters) == 0)
{
/* simple scalar: set up shortcut */
unsigned short dbfType = dbChannelFinalFieldType(chan);
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
return S_db_badDbrtype;
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
ppv_link->lastGetdbrType = dbrType;
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
path = 2;
}
else
{
/* filter, array, or special */
ppv_link->getCvt = NULL;
/* For the moment, empty arrays are not supported by EPICS */
if (dbChannelFinalElements(chan) <= 0) /* empty array request */
return S_db_badField;
if (ellCount(&chan->filters)) {
/* If filters are involved in a read, create field log and run filters */
pfl = db_create_read_log(chan);
if (!pfl)
return S_db_noMemory;
pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}
status = dbChannelGet(chan, dbrType, pbuffer, NULL, pnRequest, pfl);
if (pfl)
db_delete_field_log(pfl);
if (status)
return status;
if (pnRequest && *pnRequest <= 0) /* empty array result */
return S_db_badField;
path = 3;
}
clock_gettime(CLOCK_MONOTONIC, &stop);
if ((stop.tv_nsec -= start.tv_nsec) < 0) stop.tv_nsec += 1000000000;
errlogPrintf("dbDbGetValue(%s)[%ld] took %ld ns for %s path with %d filters\n",
chan->name, dbChannelFinalElements(chan),
stop.tv_nsec, path==1?"shortcut":path==2?"simple":"full",
ellCount(&chan->filters));
if (!status && precord != dbChannelRecord(chan))
recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode,
plink->precord,
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr);
return status;
}
--
https://code.launchpad.net/~dirk.zimoch/epics-base/+git/epics-base/+merge/378968
Your team EPICS Core Developers is subscribed to branch epics-base:7.0.
- Replies:
- Re: [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Ben Franksen via Core-talk
- References:
- [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Dirk Zimoch via Core-talk
- Navigate by Date:
- Prev:
Re: [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Dirk Zimoch via Core-talk
- Next:
Re: [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Ben Franksen via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Ben Franksen via Core-talk
- Next:
Re: [Merge] ~dirk.zimoch/epics-base:dbChannelForDBLinks into epics-base:7.0 Ben Franksen via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
|