Merged Michael's dbConvert-memmove branch.
This commit is contained in:
@@ -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 @@ static long getCharChar(
|
||||
*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 @@ static long getCharUchar(
|
||||
*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 @@ static long getUcharChar(
|
||||
*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 @@ static long getUcharUchar(
|
||||
*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 @@ static long getShortUchar(
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long getShortShort(
|
||||
const dbAddr *paddr,
|
||||
void *pto, long nRequest, long no_elements, long offset)
|
||||
@@ -881,12 +885,7 @@ static long getShortShort(
|
||||
*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 @@ static long getShortUshort(
|
||||
*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 @@ static long getUshortShort(
|
||||
*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 @@ static long getUshortUshort(
|
||||
*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 @@ static long getLongLong(
|
||||
*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 @@ static long getLongUlong(
|
||||
*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 @@ static long getUlongLong(
|
||||
*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 @@ static long getUlongUlong(
|
||||
*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 @@ static long getFloatFloat(
|
||||
*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 @@ static long getDoubleDouble(
|
||||
*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 @@ static long getEnumEnum(
|
||||
*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 @@ static long putCharChar(
|
||||
*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 @@ static long putCharUchar(
|
||||
*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 @@ static long putUcharChar(
|
||||
*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 @@ static long putUcharUchar(
|
||||
*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 @@ static long putShortShort(
|
||||
*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 @@ static long putShortUshort(
|
||||
*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 @@ static long putUshortShort(
|
||||
*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 @@ static long putUshortUshort(
|
||||
*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 @@ static long putLongLong(
|
||||
*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 @@ static long putLongUlong(
|
||||
*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 @@ static long putUlongLong(
|
||||
*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 @@ static long putUlongUlong(
|
||||
*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 @@ static long putFloatFloat(
|
||||
*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 @@ static long putDoubleDouble(
|
||||
*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 @@ static long putEnumEnum(
|
||||
*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);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define INCdbConverth
|
||||
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbAddr.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -16,6 +16,11 @@ xRec_SRCS = xRecord.c
|
||||
|
||||
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 @@ testHarness_SRCS += arrShorthandTest_registerRecordDeviceDriver.cpp
|
||||
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
|
||||
|
||||
|
||||
124
src/ioc/db/test/benchdbConvert.c
Normal file
124
src/ioc/db/test/benchdbConvert.c
Normal file
@@ -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();
|
||||
}
|
||||
@@ -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 @@ void epicsRunDbTests(void)
|
||||
{
|
||||
testHarness();
|
||||
|
||||
runTest(testdbConvert);
|
||||
runTest(callbackTest);
|
||||
runTest(dbStateTest);
|
||||
runTest(testDbChannel);
|
||||
|
||||
166
src/ioc/db/test/testdbConvert.c
Normal file
166
src/ioc/db/test/testdbConvert.c
Normal file
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user