From d6eea14fd0a127a156967c48c40b25d2a9907b67 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 11 Jan 2016 23:01:26 -0500 Subject: [PATCH] dbCa: dbCaGet/PutLink dynamic size dbCaGetLink return actual number of elements w/o zero padding. dbCaPutLink write only requested number of elements, w/o padding --- src/ioc/db/dbCa.c | 24 +++++++----------------- src/ioc/db/dbCaPvt.h | 1 + src/ioc/db/test/dbCaLinkTest.c | 34 ++++++++++------------------------ 3 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/ioc/db/dbCa.c b/src/ioc/db/dbCa.c index 5e7a609fe..981503fee 100644 --- a/src/ioc/db/dbCa.c +++ b/src/ioc/db/dbCa.c @@ -346,19 +346,16 @@ long dbCaGetLink(struct link *plink,short dbrType, void *pdest, assert(pca->pgetNative); status = fConvert(pca->pgetNative, pdest, 0); } else { - unsigned long ntoreport = *nelements, ntoget; + unsigned long ntoget = *nelements; struct dbAddr dbAddr; long (*aConvert)(struct dbAddr *paddr, void *to, long nreq, long nto, long off); aConvert = dbGetConvertRoutine[newType][dbrType]; assert(pca->pgetNative); - if (ntoreport > pca->nelements) - ntoreport = pca->nelements; - ntoget = ntoreport; if (ntoget > pca->usedelements) ntoget = pca->usedelements; - *nelements = ntoreport; + *nelements = ntoget; memset((void *)&dbAddr, 0, sizeof(dbAddr)); dbAddr.pfield = pca->pgetNative; @@ -366,12 +363,6 @@ long dbCaGetLink(struct link *plink,short dbrType, void *pdest, dbAddr.field_size = MAX_STRING_SIZE; /*Ignore error return*/ aConvert(&dbAddr, pdest, ntoget, ntoget, 0); - if(ntogetelementSize+(char*)pca->pgetNative, - 0, - (ntoreport-ntoget)*pca->elementSize); - } } done: if (pstat) *pstat = pca->stat; @@ -418,6 +409,7 @@ long dbCaPutLinkCallback(struct link *plink,short dbrType, if (!pca->pputNative) { pca->pputNative = dbCalloc(pca->nelements, dbr_value_size[ca_field_type(pca->chid)]); + pca->putnelements = 0; /* Fixed and disabled by ANJ, see comment above. plink->value.pv_link.pvlMask |= pvlOptOutNative; */ @@ -439,10 +431,7 @@ long dbCaPutLinkCallback(struct link *plink,short dbrType, if(nRequest>pca->nelements) nRequest = pca->nelements; status = aConvert(&dbAddr, pbuffer, nRequest, pca->nelements, 0); - if(nRequestnelements) { - long elemsize = dbr_value_size[ca_field_type(pca->chid)]; - memset(nRequest*elemsize+(char*)pca->pputNative, 0, (pca->nelements-nRequest)*elemsize); - } + pca->putnelements = nRequest; } link_action |= CA_WRITE_NATIVE; pca->gotOutNative = TRUE; @@ -767,6 +756,7 @@ static void eventCallback(struct event_handler_args arg) goto done; } assert(arg.dbr); + assert(arg.count<=pca->nelements); size = arg.count * dbr_value_size[arg.type]; if (arg.type == DBR_TIME_STRING && ca_field_type(pca->chid) == DBR_ENUM) { @@ -988,11 +978,11 @@ static void dbCaTask(void *arg) assert(pca->pputNative); if (pca->putType == CA_PUT) { status = ca_array_put( - pca->dbrType, pca->nelements, + pca->dbrType, pca->putnelements, pca->chid, pca->pputNative); } else if (pca->putType==CA_PUT_CALLBACK) { status = ca_array_put_callback( - pca->dbrType, pca->nelements, + pca->dbrType, pca->putnelements, pca->chid, pca->pputNative, putComplete, pca); } else { diff --git a/src/ioc/db/dbCaPvt.h b/src/ioc/db/dbCaPvt.h index b50867eda..6149d08ae 100644 --- a/src/ioc/db/dbCaPvt.h +++ b/src/ioc/db/dbCaPvt.h @@ -54,6 +54,7 @@ typedef struct caLink size_t elementSize; /* size of one element in pgetNative */ unsigned long nelements; /* PVs max array size */ unsigned long usedelements; /* currently used in pgetNative */ + unsigned long putnelements; /* currently used in pputNative */ char hasReadAccess; char hasWriteAccess; char isConnected; diff --git a/src/ioc/db/test/dbCaLinkTest.c b/src/ioc/db/test/dbCaLinkTest.c index c0b5f7b9d..43a00e8eb 100644 --- a/src/ioc/db/test/dbCaLinkTest.c +++ b/src/ioc/db/test/dbCaLinkTest.c @@ -294,45 +294,35 @@ static void fillArrayDouble(double *buf, unsigned count, double first) static void checkArray(const char *msg, epicsInt32 *buf, epicsInt32 first, - unsigned used, unsigned total) + unsigned used) { int match = 1; unsigned i; epicsInt32 x, *b; for(b=buf,x=first,i=0;inelm); + checkArray("array update", bufsrc, 1, nReq); } else { testFail("dbGetLink"); testSkip(2, "dbGetLink fails"); @@ -415,12 +405,8 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg) putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm); dbScanLock((dbCommon*)ptarg); - /* CA links always write the full target array length */ - testOp("%ld",(long)ptarg->nord,==,(long)ptarg->nelm); - /* However, if the source length is less, then the target - * is zero filled - */ - checkArray("array update", buftarg, 2, num, ptarg->nelm); + testOp("%ld",(long)ptarg->nord,==,(long)num); + dbScanUnlock((dbCommon*)ptarg); /* write again to ensure that buffer is completely updated */ @@ -429,8 +415,8 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg) putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm); dbScanLock((dbCommon*)ptarg); - testOp("%ld",(long)ptarg->nord,==,(long)ptarg->nelm); - checkArray("array update", buftarg, 3, num, ptarg->nelm); + testOp("%ld",(long)ptarg->nord,==,(long)num); + checkArray("array update", buftarg, 3, num); dbScanUnlock((dbCommon*)ptarg); testIocShutdownOk(); @@ -513,7 +499,7 @@ static void testreTargetTypeChange(void) dbScanLock((dbCommon*)psrc); testOp("%ld",(long)psrc->nord,==,(long)5); - checkArrayDouble("array update", bufsrc, 1, 5, psrc->nelm); + checkArrayDouble("array update", bufsrc, 1, 5); dbScanUnlock((dbCommon*)psrc); testDiag("Retarget"); @@ -523,7 +509,7 @@ static void testreTargetTypeChange(void) dbScanLock((dbCommon*)psrc); testOp("%ld",(long)psrc->nord,==,(long)5); - checkArrayDouble("array update", bufsrc, 2, 5, psrc->nelm); + checkArrayDouble("array update", bufsrc, 2, 5); dbScanUnlock((dbCommon*)psrc); testIocShutdownOk(); @@ -583,7 +569,7 @@ static void testCAC(void) MAIN(dbCaLinkTest) { - testPlan(91); + testPlan(87); testNativeLink(); testStringLink(); testCP();