EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base
From: mdavidsaver <[email protected]>
To: [email protected]
Date: Fri, 13 Jun 2014 19:57:21 -0000
mdavidsaver has proposed merging lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base.

Requested reviews:
  EPICS Core Developers (epics-core)

For more details, see:
https://code.launchpad.net/~epics-core/epics-base/dbConvert-memmove/+merge/223116

in dbConvert.c use memmove instead of for loop when no conversion takes place. On some archs this yields a significant speedup for array copies.
-- 
https://code.launchpad.net/~epics-core/epics-base/dbConvert-memmove/+merge/223116
Your team EPICS Core Developers is requested to review the proposed merge of lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base.
=== modified file 'src/ioc/db/dbConvert.c'
--- src/ioc/db/dbConvert.c	2014-06-04 19:18:43 +0000
+++ src/ioc/db/dbConvert.c	2014-06-13 19:56:49 +0000
@@ -38,6 +38,29 @@
 #include "recGbl.h"
 #include "dbConvert.h"
 
+/* Helper for copy as bytes with no type conversion.
+ * Assumes nRequest <= no_bytes
+ * nRequest, no_bytes, and offset should be given in bytes.
+ */
+static void copyNoConvert(const void *pfrom,
+                          void *pto,
+                          long nRequest,
+                          long no_bytes,
+                          long offset)
+{
+    if(offset>0 && offset < no_bytes && offset+nRequest > no_bytes) {
+        const size_t N = no_bytes - offset;
+        /* copy with wrap */
+        memmove(pto,     pfrom + offset, N);
+        memmove(pto + N, pfrom,          nRequest - N);
+    } else {
+        /* no wrap, just copy */
+        memmove(pto, pfrom + offset, nRequest);
+    }
+}
+#define COPYNOCONVERT(N, FROM, TO, NREQ, NO_ELEM, OFFSET) \
+    copyNoConvert(FROM, TO, (N)*(NREQ), (N)*(NO_ELEM), (N)*(OFFSET))
+
 /* DATABASE ACCESS GET CONVERSION SUPPORT */
 
 static long getStringString (
@@ -427,12 +450,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -454,12 +472,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -638,12 +651,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned char), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -658,12 +666,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(unsigned char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned char), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -870,6 +873,7 @@
     }
     return(0);
 }
+
 static long getShortShort(
     const dbAddr *paddr,
     void *pto, long nRequest, long no_elements, long offset)
@@ -881,12 +885,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(short), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -901,12 +900,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(short), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1084,12 +1078,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned short), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1104,12 +1093,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(unsigned short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned short), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1328,12 +1312,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(epicsInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(long), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1348,12 +1327,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(epicsInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(long), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1532,12 +1506,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(epicsUInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned long), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1552,12 +1521,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(epicsUInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned long), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -1782,12 +1746,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(float *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(float), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
  
@@ -2013,12 +1972,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(double *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(double), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -2228,12 +2182,7 @@
 	*pbuffer = *psrc;
 	return(0);
     }
-    psrc += offset;
-    while (nRequest) {
-	*pbuffer++ = *psrc++;
-	if(++offset==no_elements) psrc=(epicsEnum16 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsEnum16), paddr->pfield, pto, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -2734,12 +2683,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(char), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -2754,12 +2698,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned char), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -2940,12 +2879,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned char), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -2960,12 +2894,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(unsigned char *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned char), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3186,12 +3115,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(short), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3206,12 +3130,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(short), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3392,12 +3311,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned short), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3412,12 +3326,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(unsigned short *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(unsigned short), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3638,12 +3547,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(epicsInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3658,12 +3562,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(epicsUInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3844,12 +3743,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(epicsInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsUInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -3864,12 +3758,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(epicsUInt32 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsUInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -4095,12 +3984,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(float *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(float), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
  
@@ -4327,12 +4211,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(double *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(double), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 
@@ -4553,12 +4432,7 @@
 	*pdest = *pbuffer;
 	return(0);
     }
-    pdest += offset;
-    while (nRequest) {
-	*pdest++ = *pbuffer++;
-	if(++offset==no_elements) pdest=(epicsEnum16 *)paddr->pfield;
-	nRequest--;
-    }
+    COPYNOCONVERT(sizeof(epicsEnum16), pfrom, paddr->pfield, nRequest, no_elements, offset);
     return(0);
 }
 

=== modified file 'src/ioc/db/dbConvert.h'
--- src/ioc/db/dbConvert.h	2009-02-24 22:57:15 +0000
+++ src/ioc/db/dbConvert.h	2014-06-13 19:56:49 +0000
@@ -12,6 +12,7 @@
 #define INCdbConverth
 
 #include "dbFldTypes.h"
+#include "dbAddr.h"
 #include "shareLib.h"
 
 #ifdef __cplusplus

=== modified file 'src/ioc/db/test/Makefile'
--- src/ioc/db/test/Makefile	2012-07-17 19:33:31 +0000
+++ src/ioc/db/test/Makefile	2014-06-13 19:56:49 +0000
@@ -16,6 +16,11 @@
 
 PROD_LIBS = xRec dbCore ca Com
 
+TESTPROD_HOST += testdbConvert
+testdbConvert_SRCS += testdbConvert.c
+testHarness_SRCS += testdbConvert.c
+TESTS += testdbConvert
+
 TESTPROD_HOST += callbackTest
 callbackTest_SRCS += callbackTest.c
 testHarness_SRCS += callbackTest.c
@@ -56,6 +61,9 @@
 TESTFILES += $(COMMON_DIR)/arrShorthandTest.dbd
 TESTS += arrShorthandTest
 
+TESTPROD_HOST += benchdbConvert
+benchdbConvert_SRCS += benchdbConvert.c
+
 # The testHarness runs all the test programs in a known working order.
 testHarness_SRCS += epicsRunDbTests.c
 

=== added file 'src/ioc/db/test/benchdbConvert.c'
--- src/ioc/db/test/benchdbConvert.c	1970-01-01 00:00:00 +0000
+++ src/ioc/db/test/benchdbConvert.c	2014-06-13 19:56:49 +0000
@@ -0,0 +1,124 @@
+/*************************************************************************\
+* Copyright (c) 2013 Brookhaven Science Assoc, as Operator of Brookhaven
+*     National Laboratory.
+\*************************************************************************/
+#include "string.h"
+
+#include "cantProceed.h"
+#include "dbAddr.h"
+#include "dbConvert.h"
+#include "dbDefs.h"
+#include "epicsTime.h"
+#include "epicsMath.h"
+#include "epicsAssert.h"
+
+#include "epicsUnitTest.h"
+#include "testMain.h"
+
+typedef struct {
+    size_t nelem, niter;
+
+    short *output;
+    short *input;
+
+    GETCONVERTFUNC getter;
+
+    DBADDR addr;
+} testData;
+
+static long runRep(testData *D)
+{
+    size_t i;
+
+    for(i=0; i<D->niter; i++) {
+        D->getter(&D->addr, D->output, D->nelem, D->nelem, 0);
+    }
+    return 0;
+}
+
+static void runBench(size_t nelem, size_t niter, size_t nrep)
+{
+    size_t i;
+    testData tdat;
+    double *reptimes;
+    testDiag("Using %lu element arrays.",(unsigned long)nelem);
+    testDiag("run %lu reps with %lu iterations each",
+             (unsigned long)nrep, (unsigned long)niter);
+
+    reptimes = callocMustSucceed(nrep, sizeof(*reptimes), "runBench");
+    tdat.output = callocMustSucceed(nelem, sizeof(*tdat.output), "runBench");
+    tdat.input = callocMustSucceed(nelem, sizeof(*tdat.input), "runBench");
+
+    tdat.nelem = nelem;
+    tdat.niter = niter;
+
+    tdat.getter = dbGetConvertRoutine[DBF_SHORT][DBF_SHORT];
+
+    memset(&tdat.addr, 0, sizeof(tdat.addr));
+    tdat.addr.field_type = DBF_SHORT;
+    tdat.addr.field_size = nelem*sizeof(*tdat.input);
+    tdat.addr.no_elements = nelem;
+    tdat.addr.pfield = (void*)tdat.input;
+
+    for(i=0; i<nelem; i++)
+        tdat.input[i] = (short)i;
+
+    for(i=0; i<nrep; i++)
+    {
+        epicsTimeStamp start, stop;
+
+        if(epicsTimeGetCurrent(&start)!=epicsTimeOK) {
+            testAbort("Failed to get timestamp");
+            goto done;
+        }
+
+        if(runRep(&tdat))
+            goto done;
+
+        if(epicsTimeGetCurrent(&stop)!=epicsTimeOK) {
+            testAbort("Failed to get timestamp");
+            goto done;
+        }
+
+        reptimes[i] = epicsTimeDiffInSeconds(&stop, &start);
+
+        testDiag("%lu bytes in %.03f ms.  %.1f MB/s",
+                 (unsigned long)(nelem*niter),
+                 reptimes[i]*1e3,
+                 (nelem*niter)/reptimes[i]/1e6);
+    }
+
+    {
+        double sum=0, sum2=0, mean;
+        for(i=0; i<nrep; i++) {
+            sum += reptimes[i];
+            sum2 += reptimes[i]*reptimes[i];
+        }
+
+        mean = sum/nrep;
+        testDiag("Final: %.04f ms +- %.05f ms.  %.1f MB/s  (for %lu elements)",
+                 mean*1e3,
+                 sqrt(sum2/nrep - mean*mean)*1e3,
+                 (nelem*niter)/mean/1e6,
+                 (unsigned long)nelem);
+    }
+
+done:
+    free(reptimes);
+    free(tdat.input);
+    free(tdat.output);
+}
+
+MAIN(benchdbConvert)
+{
+    testPlan(0);
+    runBench(1, 10000000, 10);
+    runBench(2,  5000000, 10);
+    runBench(10, 1000000, 10);
+    runBench(100, 100000, 10);
+    runBench(10000, 1000, 10);
+    runBench(100000, 100, 10);
+    runBench(1000000, 10, 10);
+    runBench(10000000, 1, 10);
+    return testDone();
+}

=== modified file 'src/ioc/db/test/epicsRunDbTests.c'
--- src/ioc/db/test/epicsRunDbTests.c	2012-06-28 14:55:46 +0000
+++ src/ioc/db/test/epicsRunDbTests.c	2014-06-13 19:56:49 +0000
@@ -16,6 +16,7 @@
 #include "epicsExit.h"
 #include "dbmf.h"
 
+int testdbConvert(void);
 int callbackTest(void);
 int dbStateTest(void);
 int testDbChannel(void);
@@ -26,6 +27,7 @@
 {
     testHarness();
 
+    runTest(testdbConvert);
     runTest(callbackTest);
     runTest(dbStateTest);
     runTest(testDbChannel);

=== added file 'src/ioc/db/test/testdbConvert.c'
--- src/ioc/db/test/testdbConvert.c	1970-01-01 00:00:00 +0000
+++ src/ioc/db/test/testdbConvert.c	2014-06-13 19:56:49 +0000
@@ -0,0 +1,166 @@
+/*************************************************************************\
+* Copyright (c) 2013 Brookhaven Science Assoc, as Operator of Brookhaven
+*     National Laboratory.
+\*************************************************************************/
+#include "string.h"
+
+#include "cantProceed.h"
+#include "dbConvert.h"
+#include "dbDefs.h"
+#include "epicsAssert.h"
+
+#include "epicsUnitTest.h"
+#include "testMain.h"
+
+static const short s_input[] = {-1,0,1,2,3,4,5};
+static const size_t s_input_len = NELEMENTS(s_input);
+
+static void testBasicGet(void)
+{
+    short *scratch;
+    DBADDR addr;
+    GETCONVERTFUNC getter;
+
+    getter = dbGetConvertRoutine[DBF_SHORT][DBF_SHORT];
+
+    scratch = callocMustSucceed(s_input_len, sizeof(s_input), "testBasicGet");
+
+    memset(&addr, 0, sizeof(addr));
+    addr.field_type = DBF_SHORT;
+    addr.field_size = s_input_len*sizeof(*scratch);
+    addr.no_elements = s_input_len;
+    addr.pfield = (void*)s_input;
+
+    testDiag("Test dbGetConvertRoutine[DBF_SHORT][DBF_SHORT]");
+
+    {
+        testDiag("Copy out first element");
+
+        getter(&addr, scratch, 1, s_input_len, 0);
+
+        testOk1(scratch[0]==s_input[0]);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy out entire array");
+
+        getter(&addr, scratch, s_input_len, s_input_len, 0);
+
+        testOk1(memcmp(scratch, s_input, sizeof(s_input))==0);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy out partial array");
+
+        getter(&addr, scratch, 2, s_input_len, 0);
+
+        testOk1(memcmp(scratch, s_input, sizeof(short)*2)==0);
+        testOk1(scratch[2]==0x4242);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy out w/ offset");
+
+        getter(&addr, scratch, 2, s_input_len, 1);
+
+        testOk1(memcmp(scratch, s_input+1, sizeof(short)*2)==0);
+        testOk1(scratch[2]==0x4242);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy out end of array");
+
+        getter(&addr, scratch, 2, s_input_len, s_input_len-2);
+
+        testOk1(s_input_len-2 == 5);
+
+        testOk1(memcmp(scratch, s_input+5, sizeof(short)*2)==0);
+        testOk1(scratch[2]==0x4242);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy out with wrap");
+
+        getter(&addr, scratch, 2, s_input_len, s_input_len-1);
+
+        testOk1(s_input_len-2 == 5);
+
+        testOk1(scratch[0] == s_input[6]);
+        testOk1(scratch[1] == s_input[0]);
+        testOk1(scratch[2]==0x4242);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Crazy copy from out of bounds offset");
+
+        addr.pfield = (short*)(2*sizeof(short));
+
+        getter(&addr, scratch, s_input_len, s_input_len, (long)(s_input-2)/sizeof(short));
+
+        testOk1(memcmp(scratch, s_input, sizeof(s_input))==0);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    free(scratch);
+}
+
+static void testBasicPut(void)
+{
+    short *scratch;
+    DBADDR addr;
+    PUTCONVERTFUNC putter;
+
+    putter = dbPutConvertRoutine[DBF_SHORT][DBF_SHORT];
+
+    scratch = callocMustSucceed(s_input_len, sizeof(s_input), "testBasicPut");
+
+    memset(&addr, 0, sizeof(addr));
+    addr.field_type = DBF_SHORT;
+    addr.field_size = s_input_len*sizeof(*scratch);
+    addr.no_elements = s_input_len;
+    addr.pfield = (void*)scratch;
+
+    testDiag("Test dbPutConvertRoutine[DBF_SHORT][DBF_SHORT]");
+
+    {
+        testDiag("Copy in first element");
+
+        putter(&addr, s_input, 1, s_input_len, 0);
+
+        testOk1(scratch[0]==s_input[0]);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+    {
+        testDiag("Copy in entire array");
+
+        putter(&addr, s_input, s_input_len, s_input_len, 0);
+
+        testOk1(memcmp(scratch, s_input, sizeof(s_input))==0);
+
+        memset(scratch, 0x42, sizeof(s_input));
+    }
+
+}
+
+MAIN(testdbConvert)
+{
+    testPlan(16);
+    testBasicGet();
+    testBasicPut();
+    return testDone();
+}


Replies:
Re: [Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base mdavidsaver
Re: [Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base Andrew Johnson
[Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base noreply

Navigate by Date:
Prev: RE: auto-configure EPICS_CA_MAX_ARRAY_BYTES in catools/caget Hu, Yong
Next: Re: [Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base mdavidsaver
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: auto-configure EPICS_CA_MAX_ARRAY_BYTES in catools/caget Konrad, Martin
Next: Re: [Merge] lp:~epics-core/epics-base/dbConvert-memmove into lp:epics-base mdavidsaver
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 13 Jun 2014 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·