384 lines
9.3 KiB
C++
384 lines
9.3 KiB
C++
#include <cdevPlatforms.h>
|
|
#include <cdevSystem.h>
|
|
#include <cdevRequestObject.h>
|
|
#include <cdevDevice.h>
|
|
#include <cdevGroup.h>
|
|
#include <cdevCommon.h>
|
|
#include <cdevMessage.h>
|
|
|
|
struct timeval first;
|
|
int callbackCount = 0;
|
|
int reportCount = 0;
|
|
int reportFrequency = 0;
|
|
int bunchSize = 0;
|
|
char * deviceName = "device0";
|
|
char * messageStr = "set attrib0";
|
|
double PerformanceRate = 0.0;
|
|
double * performanceRatePtr = &PerformanceRate;
|
|
size_t PacketSize = 0;
|
|
size_t * packetSizePtr = &PacketSize;
|
|
int synchroValue = 0;
|
|
int synchroFound = 0;
|
|
|
|
void synchroCallback (int status, void *, cdevRequestObject &, cdevData & data)
|
|
{
|
|
if(status==CDEV_SUCCESS)
|
|
{
|
|
int value;
|
|
data.get("value", &value);
|
|
if(value==synchroValue) synchroFound = 1;
|
|
}
|
|
}
|
|
|
|
void callback ( int status, void *, cdevRequestObject &, cdevData & )
|
|
{
|
|
if(status==CDEV_SUCCESS)
|
|
{
|
|
callbackCount++;
|
|
reportCount++;
|
|
|
|
if(reportCount==reportFrequency)
|
|
{
|
|
reportCount = 0;
|
|
struct timeval second, lapsed;
|
|
|
|
gettimeofday(&second);
|
|
|
|
if (first.tv_usec > second.tv_usec)
|
|
{
|
|
second.tv_usec += 1000000;
|
|
second.tv_sec--;
|
|
}
|
|
|
|
lapsed.tv_usec = second.tv_usec - first.tv_usec;
|
|
lapsed.tv_sec = second.tv_sec - first.tv_sec;
|
|
|
|
if(lapsed.tv_sec)
|
|
{
|
|
*performanceRatePtr = (double)callbackCount/(double)lapsed.tv_sec;
|
|
fprintf(stdout, "Average rate is %lf pkts/sec after %ld packets\n", *performanceRatePtr, callbackCount);
|
|
}
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
}
|
|
|
|
cdevData * createPayload1 ( int )
|
|
{
|
|
char * binary = 0;
|
|
cdevMessage msg(1, 1, 0, 0, 0, 0, 0, 1, &deviceName, messageStr);
|
|
msg.streamOut(&binary, packetSizePtr);
|
|
delete binary;
|
|
return NULL;
|
|
}
|
|
|
|
cdevData * createPayload2 ( int cnt )
|
|
{
|
|
cdevData * data = new cdevData;
|
|
if(cnt>1)
|
|
{
|
|
int * x = new int[cnt];
|
|
for(int i=0; i<cnt; i++) x[i] = (int)i;
|
|
data->insert("value", x, cnt);
|
|
delete x;
|
|
}
|
|
else data->insert("value", 1);
|
|
|
|
char * binary = 0;
|
|
cdevMessage msg(1, 1, 0, 0, 0, 0, 0, 1, &deviceName, messageStr, data);
|
|
msg.streamOut(&binary, packetSizePtr);
|
|
delete binary;
|
|
|
|
return data;
|
|
}
|
|
|
|
cdevData * createPayload3 ( int cnt )
|
|
{
|
|
cdevData * data = new cdevData;
|
|
if(cnt>1)
|
|
{
|
|
float * x = new float[cnt];
|
|
for(int i=0; i<cnt; i++) x[i] = (float)i;
|
|
data->insert("value", x, cnt);
|
|
delete x;
|
|
}
|
|
else data->insert("value", (float)1.0);
|
|
|
|
char * binary = 0;
|
|
cdevMessage msg(1, 1, 0, 0, 0, 0, 0, 1, &deviceName, messageStr, data);
|
|
msg.streamOut(&binary, packetSizePtr);
|
|
delete binary;
|
|
|
|
return data;
|
|
}
|
|
|
|
cdevData * createPayload4 ( int cnt )
|
|
{
|
|
cdevData * data = new cdevData;
|
|
if(cnt>1)
|
|
{
|
|
double * x = new double[cnt];
|
|
for(int i=0; i<cnt; i++) x[i] = (double)i;
|
|
data->insert("value", x, cnt);
|
|
delete x;
|
|
}
|
|
else data->insert("value", (double)1.0);
|
|
|
|
char * binary = 0;
|
|
cdevMessage msg(1, 1, 0, 0, 0, 0, 0, 1, &deviceName, messageStr, data);
|
|
msg.streamOut(&binary, packetSizePtr);
|
|
delete binary;
|
|
|
|
return data;
|
|
}
|
|
|
|
cdevData * createPayload5 ( int cnt )
|
|
{
|
|
cdevData * data = new cdevData;
|
|
char buf[64];
|
|
|
|
if(cnt>1)
|
|
{
|
|
char ** x = new char *[cnt];
|
|
int i;
|
|
for(i=0; i<cnt; i++)
|
|
{
|
|
sprintf(buf, "This is string %i", i);
|
|
x[i] = strdup(buf);
|
|
}
|
|
data->insert("value", x, cnt);
|
|
for(i=0; i<cnt; i++)
|
|
{
|
|
free(x[i]);
|
|
}
|
|
delete x;
|
|
}
|
|
else
|
|
{
|
|
sprintf(buf, "This is string 0");
|
|
data->insert("value", buf);
|
|
}
|
|
|
|
char * binary = 0;
|
|
cdevMessage msg(1, 1, 0, 0, 0, 0, 0, 1, &deviceName, messageStr, data);
|
|
|
|
msg.streamOut(&binary, packetSizePtr);
|
|
delete binary;
|
|
|
|
return data;
|
|
}
|
|
|
|
const int payloadCount = 10;
|
|
|
|
char * payloadType[payloadCount] =
|
|
{
|
|
"None",
|
|
"1 - Barebones cdevMessage",
|
|
"2 - cdevMessage with one integer value",
|
|
"3 - cdevMessage with one float value",
|
|
"4 - cdevMessage with one double value",
|
|
"5 - cdevMessage with a character string",
|
|
"6 - cdevMessage with an array of integers",
|
|
"7 - cdevMessage with an array of floats",
|
|
"8 - cdevMessage with an array of doubles",
|
|
"9 - cdevMessage with an array of strings"
|
|
};
|
|
|
|
typedef cdevData * (*PayloadFunc)(int cnt);
|
|
|
|
PayloadFunc payloadFunc[payloadCount] =
|
|
{
|
|
NULL,
|
|
createPayload1,
|
|
createPayload2,
|
|
createPayload3,
|
|
createPayload4,
|
|
createPayload5,
|
|
createPayload2,
|
|
createPayload3,
|
|
createPayload4,
|
|
createPayload5
|
|
};
|
|
|
|
int main ( int argc, char ** argv )
|
|
{
|
|
int i;
|
|
int payload = 0;
|
|
int payloadItems = 0;
|
|
int count = -1;
|
|
|
|
if(argc>1) for(i=1; i<argc; i++)
|
|
{
|
|
if(*argv[i]!='-') goto QUIT_LABEL;
|
|
else {
|
|
if((i+1)>=argc) goto QUIT_LABEL;
|
|
|
|
switch (argv[i][1])
|
|
{
|
|
case 'd': // (d)evice
|
|
deviceName = strdup(argv[++i]);
|
|
break;
|
|
|
|
case 'm': // (m)essage
|
|
messageStr = strdup(argv[++i]);
|
|
break;
|
|
|
|
case 't': // payload (t)ype
|
|
payload = atoi(argv[++i]);
|
|
break;
|
|
|
|
case 'e': // payload (e)lements
|
|
payloadItems = atoi(argv[++i]);
|
|
break;
|
|
|
|
case 'b': // (b)unch size
|
|
bunchSize = atoi(argv[++i]);
|
|
break;
|
|
|
|
case 'f': // report (f)requency
|
|
reportFrequency = atoi(argv[++i]);
|
|
break;
|
|
|
|
case 'c': // packet (c)ount
|
|
count = atoi(argv[++i]);
|
|
break;
|
|
|
|
case 'h':
|
|
default:
|
|
QUIT_LABEL:
|
|
printf("\nFormat is: PerformanceTest -d dev -m msg -t type -e elements -b bunch -f freq -c count\n");
|
|
printf(" -d dev ... where dev is the name of the cdev device\n");
|
|
printf(" -m msg ... where msg is the cdev message string\n");
|
|
printf(" -t type ... where type is the outbound data's payload type\n");
|
|
for(int x=1; x<payloadCount; x++)
|
|
{
|
|
printf(" %s\n", payloadType[x]);
|
|
}
|
|
printf(" -e elements ... where elements is the number of array elements\n");
|
|
printf(" -b bunch ... where bunch is the number to send before waiting\n");
|
|
printf(" -f freq ... where freq is the report frequency\n");
|
|
printf(" -c count ... where count is the number of messages to send\n\n");
|
|
fflush(stdout);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
cdevCallback sb(synchroCallback, NULL);
|
|
cdevCallback cb(callback, NULL);
|
|
cdevData * data = NULL;
|
|
cdevData syncData;
|
|
|
|
if(payload<1 || payload>=payloadCount)
|
|
{
|
|
fprintf(stdout, "Payload type specifies the type of data that will\n");
|
|
fprintf(stdout, "transmitted in each message...\n");
|
|
for(i=1; i<payloadCount; i++)
|
|
{
|
|
fprintf(stdout, " %s\n", payloadType[i]);
|
|
}
|
|
fprintf(stdout, "\n");
|
|
|
|
while(payload<1 || payload>=payloadCount)
|
|
{
|
|
fprintf(stdout, "Enter payload type (1 - %i): ", payloadCount-1);
|
|
fscanf (stdin, "%ld", &payload);
|
|
}
|
|
}
|
|
|
|
if(payload>5)
|
|
{
|
|
if(payloadItems<1)
|
|
{
|
|
for(payloadItems = 0; payloadItems<1; )
|
|
{
|
|
fprintf(stdout, "Enter the number of array elements: ");
|
|
fscanf(stdin, "%ld", &payloadItems);
|
|
}
|
|
}
|
|
}
|
|
else payloadItems = 1;
|
|
|
|
data = payloadFunc[payload](payloadItems);
|
|
|
|
if(bunchSize<1 || bunchSize>500)
|
|
{
|
|
fprintf(stdout, "\nBunch size is the number of packets that will be\n");
|
|
fprintf(stdout, "transmitted TO the server before the application\n");
|
|
fprintf(stdout, "pauses to listen for replies FROM the server.\n\n");
|
|
while(bunchSize<1 || bunchSize>500)
|
|
{
|
|
fprintf(stdout, "Enter bunch size (1-500): ");
|
|
fscanf (stdin, "%ld", &bunchSize);
|
|
}
|
|
}
|
|
|
|
if(reportFrequency<1)
|
|
{
|
|
fprintf(stdout, "\nReport frequency is the number of packets that\n");
|
|
fprintf(stdout, "should be received from the server before the application\n");
|
|
fprintf(stdout, "pauses to calculate and report performance information.\n\n");
|
|
while(reportFrequency<1)
|
|
{
|
|
fprintf(stdout, "Enter report frequency (1 - Infinity): ");
|
|
fscanf (stdin, "%ld", &reportFrequency);
|
|
}
|
|
}
|
|
|
|
fprintf(stdout, "\nStarting Test:\n=> Device : %s\n=> Message : %s\n=> Payload : %s\n=> Packet size : %ld\n=> Bunch size : %ld\n=> Frequency : %ld\n", deviceName, messageStr, payloadType[payload], *packetSizePtr, bunchSize, reportFrequency);
|
|
if(payloadItems>1) fprintf(stdout, "=> Array Size : %ld\n", payloadItems);
|
|
if(count>0) fprintf(stdout, "=> Test Length : %ld Packets\n", count);
|
|
|
|
cdevRequestObject & req = cdevRequestObject::attachRef(deviceName, messageStr);
|
|
if(req.send(NULL, NULL)!=CDEV_SUCCESS)
|
|
{
|
|
fprintf(stdout, "\nPerformanceTest Error: Request %s %s appears to be invalid\nExiting...\n\n", deviceName, messageStr);
|
|
fflush(stdout);
|
|
return 0;
|
|
}
|
|
|
|
gettimeofday(&first);
|
|
|
|
int sendCount = 0;
|
|
cdevData recvData;
|
|
|
|
while(count<0 || sendCount<count )
|
|
{
|
|
if(bunchSize==1)
|
|
{
|
|
callback(req.send(data, recvData), NULL, req, recvData);
|
|
sendCount++;
|
|
}
|
|
else {
|
|
for(i=0; i<bunchSize; i++)
|
|
{
|
|
req.sendCallback(data, cb);
|
|
sendCount++;
|
|
}
|
|
|
|
int dryPollCount = 1;
|
|
do {
|
|
if(dryPollCount>1000)
|
|
{
|
|
fprintf(stdout, "Attempting to resynchronize after polling timeout (%i)\n", dryPollCount);
|
|
fflush (stdout);
|
|
}
|
|
|
|
synchroFound = 0;
|
|
synchroValue++;
|
|
syncData.insert("value", synchroValue);
|
|
req.sendCallback(syncData, sb);
|
|
|
|
while(!synchroFound && dryPollCount%10!=0)
|
|
{
|
|
if(cdevSystem::defaultSystem().poll()<=0) dryPollCount++;
|
|
else dryPollCount=0;
|
|
}
|
|
dryPollCount++;
|
|
} while(!synchroFound);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|