19 #include <ndb_global.h>
21 #include "TransporterRegistry.hpp"
22 #include "TransporterDefinitions.hpp"
23 #include "TransporterCallback.hpp"
24 #include <RefConvert.hpp>
31 int basePortTCP = 17000;
33 SCI_TransporterConfiguration sciTemplate = {
49 SHM_TransporterConfiguration shmTemplate = {
61 TCP_TransporterConfiguration tcpTemplate = {
81 signalHandler(
int signo){
82 ::signal(13, signalHandler);
84 sprintf(buf,
"Signal: %d\n", signo);
85 ndbout << buf << endl;
89 usage(
const char * progName){
90 ndbout <<
"Usage: " << progName <<
" <type> localNodeId localHostName"
92 <<
" [<loop count>] [<send buf size>] [<recv buf size>]" << endl;
93 ndbout <<
" type = shm tcp ose sci" << endl;
94 ndbout <<
" localNodeId - {1,2}" << endl;
97 typedef void (* CreateTransporterFunc)(
void * conf,
100 const char * localHostName,
101 const char * remoteHostName,
106 createTCPTransporter(
void*, NodeId, NodeId,
const char*,
const char*,
int,
int);
108 createSHMTransporter(
void*, NodeId, NodeId,
const char*,
const char*,
int,
int);
110 createSCITransporter(
void*, NodeId, NodeId,
const char*,
const char*,
int,
int);
116 int noOfSignalReceived;
121 Uint64 sendLenBytes, sendCount;
122 Uint64 recvLenBytes, recvCount;
126 { 1, 10, 0,0, 0,0,0,0,0,0,0 }
127 ,{ 1, 100, 0,0, 0,0,0,0,0,0,0 }
128 ,{ 1, 1000, 0,0, 0,0,0,0,0,0,0 }
129 ,{ 1, 10000, 0,0, 0,0,0,0,0,0,0 }
131 ,{ 8, 10, 0,0, 0,0,0,0,0,0,0 }
132 ,{ 8, 100, 0,0, 0,0,0,0,0,0,0 }
133 ,{ 8, 1000, 0,0, 0,0,0,0,0,0,0 }
134 ,{ 8, 10000, 0,0, 0,0,0,0,0,0,0 }
136 ,{ 16, 10, 0,0, 0,0,0,0,0,0,0 }
137 ,{ 16, 100, 0,0, 0,0,0,0,0,0,0 }
138 ,{ 16, 1000, 0,0, 0,0,0,0,0,0,0 }
139 ,{ 16, 10000, 0,0, 0,0,0,0,0,0,0 }
141 ,{ 24, 10, 0,0, 0,0,0,0,0,0,0 }
142 ,{ 24, 100, 0,0, 0,0,0,0,0,0,0 }
143 ,{ 24, 1000, 0,0, 0,0,0,0,0,0,0 }
144 ,{ 24, 10000, 0,0, 0,0,0,0,0,0,0 }
146 ,{ 0, 10, 0,0, 0,0,0,0,0,0,0 }
147 ,{ 0, 100, 0,0, 0,0,0,0,0,0,0 }
148 ,{ 0, 1000, 0,0, 0,0,0,0,0,0,0 }
149 ,{ 0, 10000, 0,0, 0,0,0,0,0,0,0 }
151 ,{ 100, 10, 0,0, 0,0,0,0,0,0,0 }
152 ,{ 100, 100, 0,0, 0,0,0,0,0,0,0 }
153 ,{ 100, 1000, 0,0, 0,0,0,0,0,0,0 }
154 ,{ 100, 10000, 0,0, 0,0,0,0,0,0,0 }
156 ,{ 500, 10, 0,0, 0,0,0,0,0,0,0 }
157 ,{ 500, 100, 0,0, 0,0,0,0,0,0,0 }
158 ,{ 500, 1000, 0,0, 0,0,0,0,0,0,0 }
159 ,{ 500, 10000, 0,0, 0,0,0,0,0,0,0 }
161 ,{ 1000, 10, 0,0, 0,0,0,0,0,0,0 }
162 ,{ 1000, 100, 0,0, 0,0,0,0,0,0,0 }
163 ,{ 1000, 1000, 0,0, 0,0,0,0,0,0,0 }
164 ,{ 1000, 10000, 0,0, 0,0,0,0,0,0,0 }
167 const int noOfTests =
sizeof(testSpec)/
sizeof(
TestPhase);
169 Uint32 StaticBuffer[1000];
172 sendSignalTo(NodeId nodeId,
int signalSize, Uint32 count){
174 signalSize = (rand() % 25) + 1;
177 sh.theLength = (signalSize > 25 ? 25 : signalSize);
178 sh.theVerId_signalNumber = count;
179 sh.theReceiversBlockNumber = rand();
180 sh.theSendersBlockRef = rand();
181 sh.theSendersSignalId = rand();
182 sh.theSignalId = rand();
183 sh.theTrace = rand();
186 for(
int i = 0;
i<25;
i++)
187 theData[
i] = (
i+1) * (Uint32)(&theData[
i]);
192 if(signalSize <= 25){
193 sh.m_noOfSections = 0;
195 sh.m_noOfSections = 1;
196 ptr[0].sz = signalSize - 25;
197 ptr[0].p = &StaticBuffer[0];
200 return tReg->
prepareSend(&sh, 1, theData, nodeId, ptr);
205 ndbout <<
"#Sigs\tSz\tTime\tSig/sec\tBps\tBps-tot\t"
206 <<
"s len\tr len" << endl;
210 print(
char * dst,
int i){
212 const int d = i / 1000000;
213 const int r = (i - (d * 1000000)) / 100000;
215 sprintf(dst,
"%d.%dM", d, r);
217 sprintf(dst,
"%dM", d);
219 const int d = i / 1000;
220 const int r = (i - (d * 1000)) / 100;
222 sprintf(dst,
"%d.%dk", d, r);
224 sprintf(dst,
"%dk", d);
226 sprintf(dst,
"%d", i);
233 Uint32 secs = (p.accTime/p.loopCount)/1000;
234 Uint32 mill = (p.accTime/p.loopCount)%1000;
237 sprintf(st,
"%d.%.2ds", secs, (mill/10));
239 sprintf(st,
"%dms", mill);
242 Uint32 sps = (1000*p.noOfSignals*p.loopCount)/p.accTime;
243 Uint32 dps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*p.signalSize);
244 Uint32 bps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(p.signalSize+3));
245 if(p.signalSize == 0){
246 dps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(13));
247 bps = ((4000*p.noOfSignals)/p.accTime)*(p.loopCount*(13+3));
259 if(p.signalSize != 0){
261 "%d\t%d\t%s\t%s\t%s\t%s\t%d\t%d",
268 (
int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
269 (
int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)));
272 "%d\trand\t%s\t%s\t%s\t%s\t%d\t%d",
278 (
int)(p.sendLenBytes / (p.sendCount == 0 ? 1 : p.sendCount)),
279 (
int)(p.recvLenBytes / (p.recvCount == 0 ? 1 : p.recvCount)));
282 ndbout << buf << endl;
290 bool isClient =
false;
291 bool isConnected =
false;
292 bool isStarted =
false;
293 int currentPhase = 0;
296 Uint32 signalsEchoed;
297 NDB_TICKS startTime, stopTime;
300 client(NodeId remoteNodeId){
304 memcpy(allPhases, testSpec,
sizeof(testSpec));
310 TestPhase * current = &allPhases[currentPhase];
311 if(current->noOfSignals == current->noOfSignalSent &&
312 current->noOfSignals == current->noOfSignalReceived){
317 current->stopTime = NdbTick_CurrentMillisecond();
318 current->accTime += (current->stopTime - current->startTime);
320 NdbSleep_MilliSleep(500 / loopCount);
322 current->startTime = NdbTick_CurrentMillisecond();
324 current->noOfSignalSent = 0;
325 current->noOfSignalReceived = 0;
327 current->loopCount ++;
328 if(current->loopCount == loopCount){
330 printReport(allPhases[currentPhase]);
333 if(currentPhase == noOfTests){
339 NdbSleep_MilliSleep(500);
340 current = &allPhases[currentPhase];
341 current->startTime = NdbTick_CurrentMillisecond();
345 int signalsLeft = current->noOfSignals - current->noOfSignalSent;
347 for(; signalsLeft > 0; signalsLeft--){
348 if(sendSignalTo(remoteNodeId,current->signalSize,sigCounter)== SEND_OK){
349 current->noOfSignalSent++;
352 ndbout <<
"Failed to send: " << sigCounter << endl;
358 if(counter % 10 == 0)
359 tReg->checkConnections();
371 for(
int i = 0; i<noOfTests; i++)
372 signalToEcho += testSpec[i].noOfSignals;
374 signalToEcho *= loopCount;
376 while(signalToEcho > signalsEchoed){
377 tReg->checkConnections();
378 for(
int i = 0; i<10; i++)
384 main(
int argc,
const char **argv){
386 const char * progName = argv[0];
404 const char *
type = argv[1];
405 const NodeId localNodeId = atoi(argv[2]);
406 const char * localHostName = argv[3];
407 const char * remoteHost1 = argv[4];
410 loopCount = atoi(argv[5]);
412 sendBufSz = atoi(argv[6]);
414 recvBufSz = atoi(argv[7]);
416 if(localNodeId < 1 || localNodeId > 2){
417 ndbout <<
"localNodeId = " << localNodeId << endl << endl;
423 ndbout <<
"-- ECHO CLIENT --" << endl;
425 ndbout <<
"-- ECHO SERVER --" << endl;
427 ndbout <<
"localNodeId: " << localNodeId << endl;
428 ndbout <<
"localHostName: " << localHostName << endl;
429 ndbout <<
"remoteHost1 (node " << (localNodeId == 1?2:1) <<
"): "
430 << remoteHost1 << endl;
431 ndbout <<
"Loop count: " << loopCount << endl;
432 ndbout <<
"-----------------" << endl;
434 void * confTemplate = 0;
435 CreateTransporterFunc func = 0;
436 if(strcasecmp(type,
"tcp") == 0){
437 func = createTCPTransporter;
438 confTemplate = &tcpTemplate;
439 }
else if(strcasecmp(type,
"sci") == 0){
440 func = createSCITransporter;
441 confTemplate = &sciTemplate;
442 }
else if(strcasecmp(type,
"shm") == 0){
443 func = createSHMTransporter;
444 confTemplate = &shmTemplate;
446 ndbout <<
"Unsupported transporter type" << endl;
450 ndbout <<
"Creating transporter registry" << endl;
452 tReg->init(localNodeId);
456 (* func)(confTemplate, 1, 2, localHostName, remoteHost1,
457 sendBufSz, recvBufSz);
460 (* func)(confTemplate, 2, 1, localHostName, remoteHost1,
461 sendBufSz, recvBufSz);
465 ndbout <<
"Doing startSending/startReceiving" << endl;
469 ndbout <<
"Connecting" << endl;
470 tReg->setPerformState(PerformConnect);
471 tReg->checkConnections();
480 ndbout <<
"Sleep 3 secs" << endl;
481 NdbSleep_SecSleep(3);
483 ndbout <<
"Doing setPerformState(Disconnect)" << endl;
484 tReg->setPerformState(PerformDisconnect);
486 ndbout <<
"Doing checkConnections()" << endl;
487 tReg->checkConnections();
489 ndbout <<
"Deleting transporter registry" << endl;
490 delete tReg; tReg = 0;
496 execute(
void* callbackObj,
SignalHeader *
const header, Uint8 prio,
497 Uint32 *
const theData,
499 const NodeId nodeId = refToNode(header->theSendersBlockRef);
502 allPhases[currentPhase].noOfSignalReceived++;
505 if(theData[0] != signalsEchoed){
506 ndbout <<
"Missing signal theData[0] = " << theData[0]
507 <<
" signalsEchoed = " << signalsEchoed << endl;
508 ndbout << (* header) << endl;
511 while(tReg->
prepareSend(header, prio, theData, nodeId, ptr) != SEND_OK){
512 ndbout <<
"Failed to echo " << theData[0] << endl;
513 NdbSleep_MilliSleep(sleepTime);
521 copy(Uint32 * & insertPtr,
527 reportError(
void* callbackObj, NodeId nodeId, TransporterError errorCode){
529 sprintf(buf,
"reportError (%d, %x) in perfTest", nodeId, errorCode);
530 ndbout << buf << endl;
531 if(errorCode & 0x8000 && errorCode != 0x8014){
540 reportSendLen(
void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
541 allPhases[currentPhase].sendCount += count;
542 allPhases[currentPhase].sendLenBytes += bytes;
545 ndbout <<
"reportSendLen(" << nodeId <<
", "
546 << (bytes/count) <<
")" << endl;
554 reportReceiveLen(
void* callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){
555 allPhases[currentPhase].recvCount += count;
556 allPhases[currentPhase].recvLenBytes += bytes;
559 ndbout <<
"reportReceiveLen(" << nodeId <<
", "
560 << (bytes/count) <<
")" << endl;
568 reportConnect(
void* callbackObj, NodeId nodeId){
570 sprintf(buf,
"reportConnect(%d)", nodeId);
571 ndbout << buf << endl;
572 tReg->setPerformState(nodeId, PerformIO);
576 startTime = NdbTick_CurrentMillisecond();
579 allPhases[0].startTime = startTime;
584 TestPhase * current = &allPhases[currentPhase];
585 current->noOfSignalSent = current->noOfSignalReceived;
593 reportDisconnect(
void* callbackObj, NodeId nodeId, Uint32 errNo){
595 sprintf(buf,
"reportDisconnect(%d)", nodeId);
596 ndbout << buf << endl;
599 tReg->setPerformState(nodeId, PerformConnect);
613 createSCITransporter(
void * _conf,
616 const char * localHostName,
617 const char * remoteHostName,
622 ndbout <<
"Creating SCI transporter from node "
623 << localNodeId <<
"(" << localHostName <<
") to "
624 << remoteNodeId <<
"(" << remoteHostName <<
")..." << endl;;
627 SCI_TransporterConfiguration * conf = (SCI_TransporterConfiguration*)_conf;
629 conf->remoteSciNodeId0= (Uint16)atoi(localHostName);
630 conf->remoteSciNodeId1= (Uint16)atoi(remoteHostName);
633 conf->localNodeId = localNodeId;
634 conf->remoteNodeId = remoteNodeId;
636 bool res = tReg->createTransporter(conf);
638 ndbout <<
"... -- Success " << endl;
640 ndbout <<
"... -- Failure " << endl;
644 createSHMTransporter(
void * _conf,
647 const char * localHostName,
648 const char * remoteHostName,
653 ndbout <<
"Creating SHM transporter from node "
654 << localNodeId <<
"(" << localHostName <<
") to "
655 << remoteNodeId <<
"(" << remoteHostName <<
")..." << endl;;
658 SHM_TransporterConfiguration * conf = (SHM_TransporterConfiguration*)_conf;
661 conf->localNodeId = localNodeId;
662 conf->remoteNodeId = remoteNodeId;
664 bool res = tReg->createTransporter(conf);
666 ndbout <<
"... -- Success " << endl;
668 ndbout <<
"... -- Failure " << endl;
673 createTCPTransporter(
void * _conf,
676 const char * localHostName,
677 const char * remoteHostName,
680 ndbout <<
"Creating TCP transporter from node "
681 << localNodeId <<
"(" << localHostName <<
") to "
682 << remoteNodeId <<
"(" << remoteHostName <<
")..." << endl;;
684 TCP_TransporterConfiguration * conf = (TCP_TransporterConfiguration*)_conf;
687 if(localNodeId == 1 && remoteNodeId == 2) port = basePortTCP + 0;
688 if(localNodeId == 1 && remoteNodeId == 3) port = basePortTCP + 1;
689 if(localNodeId == 2 && remoteNodeId == 1) port = basePortTCP + 0;
690 if(localNodeId == 2 && remoteNodeId == 3) port = basePortTCP + 2;
691 if(localNodeId == 3 && remoteNodeId == 1) port = basePortTCP + 1;
692 if(localNodeId == 3 && remoteNodeId == 2) port = basePortTCP + 2;
695 conf->sendBufferSize = sendBuf;
698 conf->maxReceiveSize = recvBuf;
701 ndbout <<
"\tSendBufferSize: " << conf->sendBufferSize << endl;
702 ndbout <<
"\tReceiveBufferSize: " << conf->maxReceiveSize << endl;
704 conf->localNodeId = localNodeId;
705 conf->localHostName = localHostName;
706 conf->remoteNodeId = remoteNodeId;
707 conf->remoteHostName = remoteHostName;
709 bool res = tReg->createTransporter(conf);
711 ndbout <<
"... -- Success " << endl;
713 ndbout <<
"... -- Failure " << endl;