1 /******************************************
2 * File: nt_bench.c
3 * Purpose: benchmarks for NT.
4 **************************************************************
5 * FILE: nt_bench.c
6 *
7 * DESCRIPTION: netapi user space transport
8 * library test application : benchmarks
9 *
10 * REVISION HISTORY: rev 0.0.1
11 *
12 * Copyright (c) Texas Instruments Incorporated 2010-2011
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * Neither the name of Texas Instruments Incorporated nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *****************************************/
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <signal.h>
49 #include <pthread.h>
50 #include <sched.h>
52 //#include "trie.h"
53 #include "string.h"
54 #include "netapi.h"
55 //#include "pktio.h"
56 #include "net_test.h"
57 #include "net_test_sa_utils.h"
58 #include "net_test_utils.h"
59 #include "net_test_thread_utils.h"
60 #include <ti/drv/sa/salld.h>
62 #if defined(DEVICE_K2H)
63 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
64 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
65 #elif defined (DEVICE_K2K)
66 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
67 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
68 #elif defined (DEVICE_K2L)
69 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
70 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
71 #elif defined (DEVICE_K2E)
72 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
73 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
74 #else /*Default */
75 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
76 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
77 #endif /* Device */
78 extern Rm_ServiceHandle *rmClientServiceHandle;
80 extern Rm_ServiceHandle *rmClientServiceHandle;
81 #define netapi_timing_start hplib_mUtilGetPmuCCNT
83 static int scnt=0;
84 static int QUIT=0;
85 static int XMIT=0;
86 static int CAP=0;
87 volatile int RESET=0; //to reset stats
89 __thread int our_core;
91 void benchmarks1(void);
92 void benchmarks2(Pktlib_HeapHandle h , int n_trials);
93 void benchmarks3(Pktlib_HeapHandle h , int n_trials);
95 //sig handler
96 void netTest_utilMySig(int x)
97 {
98 QUIT=1;
99 scnt+=1;
100 printf(">ifdma-test: recv'd signal %d cnt=%d\n",x,scnt);
101 if (scnt > 10) {printf(">ifdma-test: WARNING EXITING WITH PROPER SHUTDOWN, LUTS LEFT ACTIVE\n");exit(1);}
103 }
104 void recv_cb_net(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
105 PKTIO_METADATA_T meta[], int n_pkts,
106 uint64_t ts );
109 /*************debug********************/
110 void netTest_utilDumpDescr(unsigned long *p, int n)
111 {
112 printf("--------dump of descriptor %d %x\n", n, (int) p);
113 printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
114 printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
115 printf("-----------------------------\n");
116 }
117 void netTest_utilDumpHeader(unsigned long *p, int n, int a, int r)
118 {
119 printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);
120 printf("> %0x %0x %0x %0x %0x %0x %0x %0x\n",
121 ntohl(p[0]),ntohl(p[1]),ntohl(p[2]),ntohl(p[3]),
122 ntohl(p[4]),ntohl(p[5]),ntohl(p[6]),ntohl(p[7]) );
123 #if 0
124 printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
125 printf("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);
126 printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);
127 #endif
128 printf("-----------------------------\n");
129 }
130 /*****************************************/
133 unsigned long long CALIB=0;
134 unsigned long long calibrate_idle(void)
135 {
136 volatile unsigned long long at1;
137 volatile unsigned long long at2;
138 volatile unsigned long pt1;
139 volatile unsigned long pt2;
140 unsigned long long calib;
141 at1 = hplib_mUtilGetTimestamp();
142 pt1=netapi_timing_start();
143 for(;;)
144 {
145 pt2=netapi_timing_start() ;
146 if ((pt2-pt1) >= 100000) break;
147 }
148 at2 = hplib_mUtilGetTimestamp();
150 calib = ((unsigned long long) (pt2-pt1))/(at2-at1);
151 printf("calibrate: arm time=%lld -> arm cycles=%d calib=%lld\n", at2-at1, pt2-pt1, calib);
153 return calib;
154 }
156 /*******************************************
157 *************NETAPI OBJECTS***************
158 *****************************************/
159 static NETAPI_CFG_T our_netapi_default_cfg=
160 {
161 TUNE_NETAPI_PERM_MEM_SZ,
162 128, //start of packet offset for hw to place data on rx for default flow
163 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
164 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
165 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
166 64, //#descriptors w/o buffers in default heap
167 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
168 128, //tail room
169 256, //extra room
170 0,
171 NULL
172 };
174 Pktlib_HeapHandle OurHeap; //default heap, used by producer
175 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
176 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 12};
177 PKTIO_HANDLE_T * netcp_rx_chan;
178 PKTIO_HANDLE_T * netcp_tx_chan;
179 NETAPI_T netapi_handle;
181 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
182 PKTIO_CONTROL_T poll_cannel_control={PKTIO_SET_POLL_FLAGS, NULL, nwal_POLL_DEFAULT_GLOB_PKT_Q};
184 //template for fast path
185 nwalTxPktInfo_t txPktInfoNoCrypto =
186 {
187 NULL, /* p_pkt */
188 NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */
189 0, /* lpbackPass */
190 0, /* enetport */
191 0, /* msuSize */
192 0, /* startOffset */
193 0, /* saOffBytes */
194 0, /* saPayLoadLen */
195 0 , /* saAhIcvOffBytes */
196 0, /* saAhMacSize */
197 0,
198 /* etherLenOffBytes */
199 netTest_MAC_HEADER_LEN, /* ipOffBytes */
200 netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN, /* l4OffBytes */
201 netTest_UDP_HEADER_LEN, /* l4HdrLen */
202 0, /* pseudoHdrChecksum */
203 0 /* pLoadLen */
204 };
207 NETCP_CFG_ROUTE_T test_route=
208 {
209 0,
210 NULL,
211 NULL,
212 0//* to be filled in
213 };
216 /*************************END NETAPI OBJECTS***********************/
218 static unsigned char all_mac[]={0,0,0,0,0,0};
220 static unsigned long last_header[32/sizeof(unsigned long)];
223 //stats
224 int pkt_rx=0;
225 int pkt_tx=0;
226 unsigned long long pkt_rx_cycles=0L;
227 unsigned long long pkt_tx_cycles=0L;
228 unsigned long long pkt_cb_cycles=0L;
229 unsigned long long idle_cycles=0L;
230 volatile unsigned long long start_time;
231 unsigned long long end_time;
233 //**********************************
234 //producer thread
235 //*********************************
236 void producer_thread(int coreid)
237 {
238 int err;
239 int i;
240 Ti_Pkt * tip;
241 unsigned char * pData;
242 int len;
243 PKTIO_METADATA_T meta = {PKTIO_META_IFDMA_TX,{0},0};
244 int np;
245 cpu_set_t cpu_set;
246 unsigned long t1;
247 unsigned long t2;
249 CPU_ZERO( &cpu_set);
250 CPU_SET( 2, &cpu_set);
251 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
252 start_time = hplib_mUtilGetTimestamp();
254 //DAL we poll the default pktio channel for pkts from net
255 for(i=0;!((volatile) QUIT);i++)
256 {
257 t1 = netapi_timing_start();
258 np = netapi_pktioPoll(netcp_rx_chan,NULL,&err);
259 t2 = netapi_timing_start();
260 pkt_rx+=np;
261 if (np)
262 {
263 pkt_rx_cycles += (t2-t1);
264 }
265 else
266 {
267 idle_cycles += (t2-t1);
268 }
269 if (RESET)
270 {
271 idle_cycles=0LL;
272 start_time = hplib_mUtilGetTimestamp();
273 pkt_rx=pkt_tx=0;
274 pkt_rx_cycles=pkt_tx_cycles=0LL;
275 pkt_cb_cycles=0LL;
276 RESET=0;
277 }
278 }
279 end_time = hplib_mUtilGetTimestamp();
280 printf("nt-bench: receiver DONE %d pkts rx, pkt poll cycles=% u; pkt rx cycle=%u pkt tx cycles=%u idle cycles=%lld duration=%lld ticks idle pct= %lld\n",
281 pkt_rx,
282 (unsigned) (pkt_rx ? (pkt_rx_cycles - pkt_cb_cycles)/pkt_rx : 0),
283 (unsigned) (pkt_rx ? (pkt_rx_cycles) /pkt_rx : 0),
284 (unsigned) (pkt_tx ? (pkt_tx_cycles) /pkt_tx : 0),
285 idle_cycles, (end_time-start_time),
286 (idle_cycles*100) /( CALIB* (end_time-start_time))
288 );
289 printf("Leaving producer_thread\n");
290 }
293 //******************************
294 // main program
295 //*****************************
296 int main(int argc, char **argv)
297 {
298 int err,i;
299 int32_t errCode;
300 Pktlib_HeapIfTable* pPktifTable;
301 Pktlib_HeapCfg heapCfg;
302 long t1, t2 ;
303 cpu_set_t cpu_set;
306 //install signal handler for ^c
307 signal(SIGINT,netTest_utilMySig);
309 if (initRm())
310 {
311 printf("main: initRm() returned error\n");
312 exit(1);
313 }
315 CPU_ZERO( &cpu_set);
316 CPU_SET( 0, &cpu_set);
317 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
320 /*******************************************/
321 /*************NETAPI STARTUP****************/
322 /*******************************************/
324 /* create netapi */
325 our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
326 netapi_handle = netapi_init(NETAPI_SYS_MASTER,
327 &our_netapi_default_cfg);
328 if (netapi_handle == NULL)
329 {
330 printf("main: netapi_init failure, exiting\n");
331 exit(1);
332 }
333 netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
335 /* open the main heap */
336 OurHeap = Pktlib_findHeapByName("netapi");
337 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
339 //if we want to relay network packets, we create a handle to the
340 //default netcp receive queue here
341 netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_net, &netcp_rx_cfg, &err);
342 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
344 netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg, &err);
345 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
346 else //install a fast path template into the NETCP TX channel
347 {
348 PKTIO_CONTROL_T control2;
349 control2.op = PKTIO_UPDATE_FAST_PATH;
350 PKTIO_CFG_T cfg2;
351 cfg2.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
352 cfg2.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
353 netapi_pktioControl(netcp_tx_chan, NULL, &cfg2, &control2, &err);
354 }
357 /*********************************************/
358 /*****************end NETAPI STARTUP**********/
359 /*********************************************/
361 /*************************************************
362 ********************some basic benchmarks*********
363 **************************************************/
364 printf("\n\n*******STARTING MEM ACCESS BENCHMARK*********\n\n");
365 benchmarks1();
366 printf("\n\n*******STARTING RAW BENCHMARK2*********\n\n");
367 benchmarks2(OurHeap, 20);
368 printf("\n\n*******STARTING RAW BENCHMARK3*********\n\n");
369 benchmarks3(OurHeap, 20);
370 printf("\n\n******STARTING RECV BENCHMARK (q to quit)*****\n\n");
373 //now creaate a simple netcp rule
374 //to get a lot of packets
375 netapi_netcpCfgCreateMacInterface(
376 netapi_handle,
377 &all_mac[0],
378 NULL,
379 0,0,
380 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
381 (NETCP_CFG_VLAN_T ) NULL , //future
382 1,
383 &err);
385 //calibrate idle
386 CALIB = calibrate_idle();
388 //**************************************
389 //Create a worked thread
390 //***************************************
391 {
392 pthread_t *thrs;
393 int procs =1;
394 char c;
395 thrs = malloc( sizeof( pthread_t ) * procs );
396 if (thrs == NULL)
397 {
398 perror( "malloc" );
399 return -1;
400 }
401 printf( "benchmark-test: Starting %d threads...\n", procs );
403 if (pthread_create( &thrs[0], NULL, (void*)producer_thread,
404 (void *)0 ))
405 {
406 perror( "pthread_create" );
407 exit(1);
408 }
409 //this thread of execution (main) now just waits on user input
410 for(;;)
411 {
412 printf(">");
413 c=getchar();
414 if (c=='c') {CAP=!CAP; printf("CAPTURE= %d\n", CAP); }
415 else if (c=='q') {QUIT=1;break;}
416 else if (c=='t') {XMIT=!XMIT; printf("XMIT= %d\n", XMIT); }
417 else if (c=='s')
418 {
419 unsigned long long et= hplib_mUtilGetTimestamp();
420 printf(">NT_BENCH STATS: %d received %d xmitted, %lld idle cycles, %lld duration ticks idle=%lld\n",
421 pkt_rx,pkt_tx,
422 idle_cycles,
423 (et-start_time),
424 (idle_cycles*100)/(CALIB*(et-start_time)));
425 Pktlib_HeapStats pktLibHeapStats;
426 Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
427 printf("main heap stats> #free=%d #zb=%d #garbage=%d\n",
428 pktLibHeapStats.numFreeDataPackets,
429 pktLibHeapStats.numZeroBufferPackets,
430 pktLibHeapStats.numPacketsinGarbage);
431 }
432 else if (c=='r')
433 {
434 RESET=1;
435 }
436 else if (c=='h')
437 {
438 printf("> 'q' to quit, 's' for stats, 't' to toggle transmit 'c' to toggle capture, 'd' to dump capture, 'r' to reset idle counters, 'h' for help\n");
439 }
440 else if (c=='d')
441 {
442 netTest_utilDumpHeader(&last_header[0], 0,0,0);
443 }
444 }
446 //wait for completion
447 printf("main task now pending on thread completion\n");
448 for (i = 0; i < procs; i++)
449 pthread_join( thrs[i], NULL );
451 free( thrs );
453 }
455 /*************************************************
456 ************CLEAN UP****************************
457 ************************************************/
458 //get rid of rule, in the case that we are relaying packets
459 //also close our netcp rx channel
460 netapi_netcpCfgDelMac(netapi_handle,0,&err);
461 netapi_pktioClose(netcp_rx_chan,&err);
462 netapi_pktioClose(netcp_tx_chan,&err);
465 //done
466 netapi_shutdown(netapi_handle);
469 //!finished!
470 }
471 static inline void sendit(Ti_Pkt *tip, int len, int out_port)
472 {
473 int err=0;
474 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
475 nwalTxPktInfo_t meta_tx2={0};
476 if (len<60)
477 {
478 unsigned int templen;
479 char * p_pkt;
480 len=60;
481 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
482 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
483 }
484 Pktlib_setPacketLen(tip,len);
485 meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID ;
486 meta_tx2.ploadLen = len ;
487 meta_tx2.enetPort=out_port;
488 meta2.u.tx_meta=&meta_tx2;
489 netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);
490 }
492 //receive callback for packets from net (for consumer)
493 void recv_cb_net(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
494 PKTIO_METADATA_T meta[], int n_pkts,
495 uint64_t ts )
496 {
497 int i;
498 Ti_Pkt * tip;
499 int len;
500 unsigned long t1;
501 unsigned long t2;
502 unsigned long t3;
503 unsigned long t4;
504 pasahoLongInfo_t* protoInfo;
505 int ifno;
506 int out_port;
508 t1= netapi_timing_start();
509 for(i=0;i<n_pkts;i++)
510 {
511 tip = p_recv[i];
512 len = Pktlib_getPacketLen(tip);
514 if (CAP)
515 {
516 unsigned int templen;
517 char * p_pkt;
518 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
519 memcpy(last_header,p_pkt,32);
520 }
522 if (XMIT)
523 {
524 protoInfo=nwal_mGetProtoInfo(tip);
525 ifno = nwal_mGetRxEmacPort( protoInfo);
526 //----------------------------------------------------
527 //very trivial bridging -> just output to other port!
528 //----------------------------------------------------
529 if (ifno ==1) out_port=2; else out_port=1;
530 t3= netapi_timing_start();
531 sendit(tip,len,out_port);
532 pkt_tx+=1;
533 t4= netapi_timing_start();
534 pkt_tx_cycles += (t4-t3);
535 }
536 else
537 {
538 Pktlib_freePacket((Ti_Pkt*)tip);
539 }
540 }
541 t2 = netapi_timing_start();
542 pkt_cb_cycles += (t2-t1);
543 }
548 //SOME BENCHMARKS
549 //sonme benchmarks
550 void benchmarks1(void)
551 {
552 int i,j;
553 unsigned long v1pop;
554 unsigned long v2pop;
555 unsigned long v1push;
556 unsigned long v2push;
557 unsigned long v1read;
558 unsigned long v2read;
559 unsigned long v1write;
560 unsigned long v2write;
561 unsigned long v1read2;
562 unsigned long v2read2;
563 #define N 100
564 Ti_Pkt pkts[N];
565 unsigned char * p_pkt;
566 int len;
567 int sum=0;
568 int sum2=0;
569 char *p=(char *) malloc(1000);
570 //alloc
571 v1pop=netapi_timing_start();
572 for(i=0;i<N;i++) pkts[i]= Pktlib_allocPacket(OurHeap,1000);
573 v2pop = netapi_timing_start();
575 //write access
576 Pktlib_getDataBuffer(pkts[0],(uint8_t**)&p_pkt,&len);
577 v1write=netapi_timing_start();
578 for(i=0;i<1000;i++) p_pkt[i]=i;
579 v2write=netapi_timing_start();
581 //read access
582 v1read=netapi_timing_start();
583 for(j=0;j<10;j++)
584 for(i=0;i<1000;i++) sum+=p_pkt[i];
585 v2read=netapi_timing_start();
587 // access (from malloc)
588 v1read2=netapi_timing_start();
589 for(i=0;i<1000;i++) sum2+=p[i];
590 v2read2=netapi_timing_start();
592 //free packet
593 v1push=netapi_timing_start();
594 for(i=0;i<N;i++) Pktlib_freePacket(pkts[i]);
595 v2push = netapi_timing_start();
597 //resutls
598 printf("allocs= %d free=%d write=%d read=%d read-malloc=%d (sum=%d %d)\n",
599 (v2pop-v1pop)/N, (v2push-v1push)/N, (v2write-v1write)/1000, (v2read-v1read)/10000,
600 (v2read2-v1read2)/1000,sum,sum2);
603 };
606 //raw queue benchmark
607 #include "ti/drv/nwal/nwal_util.h"
609 #define NTOPOP 150
610 volatile unsigned long t1;
611 volatile unsigned long t2;
612 volatile unsigned long t3;
613 volatile unsigned long t4;
614 volatile unsigned long t5;
615 volatile unsigned long t6;
616 volatile unsigned long sum1=0;
617 volatile unsigned long sum2=0;
618 volatile unsigned long sum3=0;
619 volatile unsigned long sum4=0;
620 volatile Ti_Pkt * pHd[NTOPOP];
623 void benchmarks2(Pktlib_HeapHandle h , int ntrials)
624 {
625 int i,j;
626 int k;
627 int abort=0;
628 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);
630 //n_trials of NTOPOP actions
631 for(i=0;i<ntrials;i++)
632 {
633 abort=0;
634 sum1=sum2=sum3=sum4=0;
635 //raw pop
636 t1= netapi_timing_start();
637 for(j=0;j<NTOPOP;j++)
638 {
639 pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(pktio_mQmssQueuePopRaw (freeQ));
640 if (!pHd[j])
641 {
642 printf("abort test. out of descriptors\n"); abort=1;
643 break;
644 }
645 }
646 t2= netapi_timing_start();
647 k=j;
648 for(j=0;j<k;j++)
649 {
650 pHd[j] = Osal_qmssConvertDescPhyToVirt(0,pHd[j]);
651 }
652 t3= netapi_timing_start();
653 sum1 += (t2-t1);
654 sum2 += (t3-t2);
655 //raw push
656 t4= netapi_timing_start();
657 for(j=0;j<k;j++)
658 {
659 if (!pHd[j]) continue;
660 pHd[j]= Osal_qmssConvertDescVirtToPhy(0,pHd[j]);
661 }
662 t5= netapi_timing_start();
663 for(j=0;j<k;j++)
664 {
665 pktio_mQmssQueuePushDescSizeRaw(freeQ,
666 (void *) pHd[j],
667 128);
668 }
669 t6= netapi_timing_start();
670 sum3 += (t5-t4);
671 sum4 += (t6-t5);
673 if (!abort)
674 printf("nt=%d raw pop=%d p2v=%d v2p=%d raw push=%d\n", i,
675 sum1/k, sum2/k, sum3/k, sum4/k);
676 sleep(1);
677 }
678 return;
679 }
681 //full queue push/pops
682 void benchmarks3(Pktlib_HeapHandle h , int ntrials)
683 {
684 int i,j;
685 int k;
686 int abort=0;
687 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);
689 //n_trials of NTOPOP actions
690 for(i=0;i<ntrials;i++)
691 {
692 abort=0;
693 sum2=sum4=0;
694 //raw pop
695 t1= netapi_timing_start();
696 for(j=0;j<NTOPOP;j++)
697 {
698 pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(Qmss_queuePop(freeQ));
699 if (!pHd[j])
700 {
701 printf("abort test. out of descriptors\n"); abort=1;
702 break;
703 }
704 }
705 t3= netapi_timing_start();
706 sum2 += (t3-t1);
707 k=j;
708 //raw push
709 t5= netapi_timing_start();
710 for(j=0;j<k;j++)
711 {
712 if (!pHd[j]) continue;
713 Qmss_queuePushDescSize(freeQ, pHd[j], 128);
714 }
715 t6= netapi_timing_start();
716 sum4 += (t6-t5);
717 if (!abort)
718 printf("nt=%d pop=%d push=%d\n", i,
719 sum2/k, sum4/k);
720 sleep(1);
721 }
722 return;
723 }