Updates to net_test_bench application, removed net_test_setup.sh
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test_bench.c
1 /******************************************\r
2  * File: nt_bench.c   \r
3  * Purpose:  benchmarks for NT.\r
4  **************************************************************\r
5  * FILE:  nt_bench.c\r
6  * \r
7  * DESCRIPTION:  netapi user space transport\r
8  *               library  test application : benchmarks\r
9  * \r
10  * REVISION HISTORY:  rev 0.0.1 \r
11  *\r
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011\r
13  * \r
14  *  Redistribution and use in source and binary forms, with or without \r
15  *  modification, are permitted provided that the following conditions \r
16  *  are met:\r
17  *\r
18  *    Redistributions of source code must retain the above copyright \r
19  *    notice, this list of conditions and the following disclaimer.\r
20  *\r
21  *    Redistributions in binary form must reproduce the above copyright\r
22  *    notice, this list of conditions and the following disclaimer in the \r
23  *    documentation and/or other materials provided with the   \r
24  *    distribution.\r
25  *\r
26  *    Neither the name of Texas Instruments Incorporated nor the names of\r
27  *    its contributors may be used to endorse or promote products derived\r
28  *    from this software without specific prior written permission.\r
29  *\r
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
41 \r
42  *****************************************/\r
43 \r
44 #include <stdio.h>\r
45 #include <stdlib.h>\r
46 #include <unistd.h>\r
47 #include <string.h>\r
48 #include <signal.h>\r
49 #include <pthread.h>\r
50 #include <sched.h>\r
51 \r
52 #include "trie.h"\r
53 #include "string.h"\r
54 #include "netapi.h"\r
55 #include "pktio.h"\r
56 #include "net_test.h"\r
57 #include <ti/drv/sa/salld.h>\r
58 \r
59 #define netapi_timing_start hplib_mUtilGetPmuCCNT\r
60 \r
61 static int scnt=0;\r
62 static int QUIT=0;\r
63 static int XMIT=0;\r
64 __thread int our_core;\r
65 \r
66 void benchmarks1(void);\r
67 void benchmarks2(Pktlib_HeapHandle h , int n_trials);\r
68 void benchmarks3(Pktlib_HeapHandle h , int n_trials);\r
69 \r
70 //sig handler\r
71 void netTest_utilMySig(int x)\r
72 {\r
73   QUIT=1;\r
74   scnt+=1;\r
75   printf(">ifdma-test: recv'd signal %d cnt=%d\n",x,scnt);\r
76   if (scnt > 10) {printf(">ifdma-test: WARNING EXITING WITH PROPER SHUTDOWN, LUTS LEFT ACTIVE\n");exit(1);}\r
77 \r
78 }\r
79 void recv_cb_net(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
80                          PKTIO_METADATA_T meta[], int n_pkts,\r
81                          uint64_t ts );\r
82 \r
83 \r
84 /*************debug********************/\r
85 void netTest_utilDumpDescr(unsigned long *p, int n)\r
86 {\r
87    printf("--------dump of descriptor %d %x\n", n, (int) p);\r
88    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]);\r
89    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]);\r
90    printf("-----------------------------\n");\r
91 }\r
92 void netTest_utilDumpHeader(unsigned long *p, int n, int a, int r)\r
93 {\r
94    printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);\r
95    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]);\r
96    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]);\r
97    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]);\r
98    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]);\r
99    printf("-----------------------------\n");\r
100 }\r
101 /*****************************************/\r
102 \r
103 \r
104 \r
105 \r
106 \r
107 \r
108 \r
109 /*******************************************\r
110  *************NETAPI OBJECTS***************\r
111  *****************************************/\r
112 static NETAPI_CFG_T our_netapi_default_cfg=\r
113 {\r
114 TUNE_NETAPI_PERM_MEM_SZ,\r
115 128,  //start of packet offset for hw to place data on rx for default flow\r
116 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system\r
117 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use\r
118 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap\r
119 64, //#descriptors w/o buffers in default heap\r
120 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap\r
121 128   ,  //tail room\r
122 256      //extra room \r
123 };\r
124 \r
125 Pktlib_HeapHandle OurHeap;     //default heap, used by producer\r
126 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};\r
127 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};\r
128 PKTIO_HANDLE_T * netcp_rx_chan;\r
129 PKTIO_HANDLE_T * netcp_tx_chan;\r
130 NETAPI_T netapi_handle;\r
131 \r
132 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};\r
133 \r
134 NETCP_CFG_ROUTE_T  test_route=\r
135 {\r
136 NULL, NULL  //* to be filled in\r
137 };\r
138 \r
139 \r
140 /*************************END NETAPI OBJECTS***********************/\r
141 \r
142 static unsigned char all_mac[]={0,0,0,0,0,0};\r
143 \r
144 \r
145 \r
146 //stats\r
147 int pkt_rx=0; \r
148 int pkt_tx=0; \r
149 unsigned long long pkt_rx_cycles=0;\r
150 unsigned long long pkt_tx_cycles=0;\r
151 unsigned long long pkt_cb_cycles=0;\r
152 \r
153 \r
154 //**********************************\r
155 //producer thread\r
156 //*********************************\r
157 void producer_thread(int coreid)\r
158 {\r
159 int err;\r
160 int i;\r
161 Ti_Pkt * tip;\r
162 unsigned char * pData;\r
163 int len;\r
164 PKTIO_METADATA_T meta = {PKTIO_META_IFDMA_TX,{0},0};\r
165 int np;\r
166 cpu_set_t cpu_set;\r
167 unsigned long t1;\r
168 unsigned long t2;\r
169 \r
170     CPU_ZERO( &cpu_set);\r
171     CPU_SET( 2, &cpu_set);\r
172     hplib_utilSetupThread(2, &cpu_set);\r
173 \r
174      //DAL we poll the default pktio channel for pkts from net\r
175       for(i=0;!((volatile) QUIT);i++)\r
176       {\r
177         t1 = netapi_timing_start();\r
178         np = netapi_pktioPoll(netcp_rx_chan,NULL,&err);\r
179         t2 = netapi_timing_start();\r
180         pkt_rx+=np;\r
181         if (np) \r
182         {\r
183            pkt_rx_cycles += (t2-t1);\r
184         }\r
185       }\r
186       printf("nt-bench: receiver  DONE %d pkts rx,  pkt poll cycles=% u; pkt rx cycle=%u pkt tx cycles=%u \n", pkt_rx,\r
187              (unsigned)  (pkt_rx ?  (pkt_rx_cycles - pkt_cb_cycles)/pkt_rx : 0),\r
188              (unsigned)  (pkt_rx ?  (pkt_rx_cycles) /pkt_rx : 0),\r
189              (unsigned)  (pkt_tx ?  (pkt_tx_cycles) /pkt_tx : 0)\r
190             );\r
191      printf("Leaving producer_thread\n");\r
192 }\r
193 \r
194 \r
195 //******************************\r
196 //  main program\r
197 //*****************************\r
198 int main(int argc, char **argv)\r
199 {\r
200     int err,i;\r
201     int32_t             errCode;\r
202     Pktlib_HeapIfTable*  pPktifTable;\r
203     Pktlib_HeapCfg heapCfg;\r
204     long t1, t2 ;\r
205     cpu_set_t cpu_set;\r
206 \r
207 \r
208      //install signal handler for ^c\r
209     signal(SIGINT,netTest_utilMySig);\r
210 \r
211 \r
212 \r
213 \r
214 \r
215 \r
216     CPU_ZERO( &cpu_set);\r
217     CPU_SET( 0, &cpu_set);\r
218     hplib_utilSetupThread(2, &cpu_set);\r
219 \r
220 \r
221     /*******************************************/\r
222     /*************NETAPI STARTUP****************/\r
223     /*******************************************/\r
224 \r
225     /* create netapi */\r
226     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);\r
227     netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);\r
228 \r
229     /* open the main heap */\r
230     OurHeap = Pktlib_findHeapByName("netapi");\r
231     if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}\r
232 \r
233     //if we want to relay network packets, we create a handle to the \r
234     //default netcp receive queue here\r
235     netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_net, &netcp_rx_cfg,  &err);\r
236     if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}\r
237 \r
238     netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg,  &err);\r
239     if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}\r
240 \r
241 /*********************************************/\r
242 /*****************end NETAPI STARTUP**********/\r
243 /*********************************************/\r
244 \r
245 /*************************************************\r
246 ********************some basic benchmarks*********\r
247 **************************************************/\r
248 printf("\n\n*******STARTING MEM ACCESS BENCHMARK*********\n\n");\r
249 benchmarks1();\r
250 printf("\n\n*******STARTING RAW BENCHMARK2*********\n\n");\r
251 benchmarks2(OurHeap, 20);\r
252 printf("\n\n*******STARTING RAW BENCHMARK3*********\n\n");\r
253 benchmarks3(OurHeap, 20);\r
254 printf("\n\n******STARTING RECV BENCHMARK (q to quit)*****\n\n");\r
255 \r
256 \r
257 //now creaate a simple netcp rule\r
258 //to get a lot of packets\r
259 netapi_netcpCfgCreateMacInterface(\r
260                   netapi_handle,\r
261                   &all_mac[0],\r
262                   0,0,\r
263                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
264                   (NETCP_CFG_VLAN_T ) NULL ,  //future\r
265                   1,\r
266                   &err);\r
267 \r
268 //**************************************\r
269 //Create a worked thread\r
270 //***************************************\r
271 {\r
272         pthread_t *thrs;\r
273         int procs =1; \r
274         char c;\r
275         thrs = malloc( sizeof( pthread_t ) * procs );\r
276         if (thrs == NULL)\r
277         {\r
278                 perror( "malloc" );\r
279                 return -1;\r
280         }\r
281         printf( "benchmark-test: Starting %d threads...\n", procs );\r
282 \r
283         if (pthread_create( &thrs[0], NULL, (void*)producer_thread,\r
284                         (void *)0 ))\r
285         {\r
286                         perror( "pthread_create" );\r
287                         exit(1);\r
288         }\r
289         //this thread of execution (main) now just waits on user input\r
290         for(;;)\r
291         {\r
292            printf(">");\r
293            c=getchar();\r
294            if (c=='q') {QUIT=1;break;}\r
295            if (c=='t') {XMIT=!XMIT; printf("XMIT= %d\n", XMIT); }\r
296            else if (c=='s') printf(">IFDMA-TEST STATS:    %d received   %d xmitted \n", pkt_rx,pkt_tx);\r
297            else if (c=='h') printf("> 'q' to quit,  's' for stats, 't' to toggle transmit  'h' for help\n");\r
298         }\r
299 \r
300         //wait for completion \r
301         printf("main task now pending on thread completion\n");\r
302         for (i = 0; i < procs; i++)\r
303                 pthread_join( thrs[i], NULL );\r
304 \r
305         free( thrs );\r
306       \r
307 }\r
308 \r
309 /*************************************************\r
310  ************CLEAN UP****************************\r
311  ************************************************/\r
312 //get rid of rule, in the case that we are relaying packets\r
313 //also close our netcp rx channel\r
314 netapi_netcpCfgDelMac(netapi_handle,0,&err);\r
315 netapi_pktioClose(netcp_rx_chan,&err);\r
316 netapi_pktioClose(netcp_tx_chan,&err);\r
317 \r
318 \r
319 //done\r
320 netapi_shutdown(netapi_handle);\r
321 \r
322 \r
323 //!finished!\r
324 }\r
325 static inline void sendit(Ti_Pkt *tip, int len, int out_port)\r
326 {\r
327   int err=0;\r
328   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};\r
329   nwalTxPktInfo_t meta_tx2={0};\r
330   if (len<60)\r
331   {\r
332      unsigned int templen;\r
333      char * p_pkt;\r
334      len=60;\r
335      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
336      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);\r
337   }\r
338   Pktlib_setPacketLen(tip,len);\r
339   meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID ; \r
340   meta_tx2.ploadLen = len ;\r
341   meta_tx2.enetPort=out_port;\r
342   meta2.u.tx_meta=&meta_tx2;\r
343   netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);\r
344 }\r
345 \r
346 //receive callback for packets from net (for consumer)\r
347 void recv_cb_net(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
348                          PKTIO_METADATA_T meta[], int n_pkts,\r
349                          uint64_t ts )\r
350 {\r
351 int i;\r
352 Ti_Pkt * tip;\r
353 int len;\r
354 unsigned long t1;\r
355 unsigned long t2;\r
356 unsigned long t3;\r
357 unsigned long t4;\r
358 pasahoLongInfo_t* protoInfo; \r
359 int ifno;\r
360 int out_port;\r
361 \r
362 t1= netapi_timing_start();\r
363 for(i=0;i<n_pkts;i++)\r
364 {\r
365     tip = p_recv[i];\r
366     len = Pktlib_getPacketLen(tip);\r
367     if (XMIT)\r
368     {\r
369         protoInfo=nwal_mGetProtoInfo(tip);\r
370         ifno = nwal_mGetRxEmacPort( protoInfo);\r
371         //----------------------------------------------------\r
372         //very trivial bridging -> just output to other port!\r
373         //----------------------------------------------------\r
374         if (ifno ==1) out_port=2; else out_port=1;\r
375 \r
376        t3= netapi_timing_start();\r
377        sendit(tip,len,out_port);\r
378        pkt_tx+=1;\r
379        t4= netapi_timing_start();\r
380        pkt_tx_cycles += (t4-t3);\r
381     }\r
382     else\r
383       Pktlib_freePacket((Ti_Pkt*)tip);\r
384 }\r
385 t2 = netapi_timing_start();\r
386 pkt_cb_cycles += (t2-t1);\r
387 }\r
388 \r
389 \r
390 \r
391 \r
392 //SOME BENCHMARKS\r
393 //sonme benchmarks\r
394 void benchmarks1(void)\r
395 {\r
396 int i,j;\r
397 unsigned long v1pop;\r
398 unsigned long v2pop;\r
399 unsigned long v1push;\r
400 unsigned long v2push;\r
401 unsigned long v1read;\r
402 unsigned long v2read;\r
403 unsigned long v1write;\r
404 unsigned long v2write;\r
405 unsigned long v1read2;\r
406 unsigned long v2read2;\r
407 #define N 100\r
408 Ti_Pkt  pkts[N];\r
409 unsigned char * p_pkt;\r
410 int len;\r
411 int sum=0;\r
412 int sum2=0;\r
413 char *p=(char *) malloc(1000);\r
414 //alloc\r
415 v1pop=netapi_timing_start();\r
416 for(i=0;i<N;i++)   pkts[i]= Pktlib_allocPacket(OurHeap,1000);\r
417 v2pop = netapi_timing_start();\r
418 \r
419 //write access\r
420 Pktlib_getDataBuffer(pkts[0],(uint8_t**)&p_pkt,&len);\r
421 v1write=netapi_timing_start();\r
422 for(i=0;i<1000;i++) p_pkt[i]=i;\r
423 v2write=netapi_timing_start();\r
424 \r
425 //read access\r
426 v1read=netapi_timing_start();\r
427 for(j=0;j<10;j++)\r
428 for(i=0;i<1000;i++) sum+=p_pkt[i];\r
429 v2read=netapi_timing_start();\r
430 \r
431 // access (from malloc)\r
432 v1read2=netapi_timing_start();\r
433 for(i=0;i<1000;i++) sum2+=p[i];\r
434 v2read2=netapi_timing_start();\r
435 \r
436 //free packet\r
437 v1push=netapi_timing_start();\r
438 for(i=0;i<N;i++)   Pktlib_freePacket(pkts[i]);\r
439 v2push = netapi_timing_start();\r
440 \r
441 //resutls\r
442 printf("allocs= %d  free=%d   write=%d  read=%d read-malloc=%d (sum=%d %d)\n",\r
443         (v2pop-v1pop)/N, (v2push-v1push)/N,  (v2write-v1write)/1000, (v2read-v1read)/10000,\r
444         (v2read2-v1read2)/1000,sum,sum2);\r
445 \r
446 \r
447 };\r
448 \r
449 \r
450 //raw queue benchmark\r
451 #include "ti/drv/nwal/nwal_util.h"\r
452 \r
453 #define NTOPOP 150\r
454 volatile unsigned long t1;\r
455 volatile unsigned long t2;\r
456 volatile unsigned long t3;\r
457 volatile unsigned long t4;\r
458 volatile unsigned long t5;\r
459 volatile unsigned long t6;\r
460 volatile unsigned long sum1=0;\r
461 volatile unsigned long sum2=0;\r
462 volatile unsigned long sum3=0;\r
463 volatile unsigned long sum4=0;\r
464 volatile Ti_Pkt * pHd[NTOPOP];\r
465 \r
466 void * pop_raw(int n)\r
467 {\r
468 \r
469 }\r
470 void * p2v (void* in)\r
471 {\r
472 \r
473 \r
474 }\r
475 void * v2p(void * in)\r
476 {\r
477 \r
478 }\r
479 void push_raw(void *pkt, int n)\r
480 {\r
481 \r
482 }\r
483 \r
484 void benchmarks2(Pktlib_HeapHandle h , int ntrials)\r
485 {\r
486 int i,j;\r
487 int k;\r
488 int abort=0;\r
489 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);\r
490 \r
491 //n_trials of NTOPOP actions\r
492 for(i=0;i<ntrials;i++)\r
493 {\r
494     abort=0;\r
495     sum1=sum2=sum3=sum4=0;\r
496     //raw pop\r
497     t1= netapi_timing_start();\r
498     for(j=0;j<NTOPOP;j++)\r
499     {\r
500        pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(pktio_mQmssQueuePopRaw (freeQ));\r
501        if (!pHd[j]) \r
502        {\r
503          printf("abort test. out of descriptors\n"); abort=1;\r
504          break;\r
505        }\r
506     }\r
507     t2= netapi_timing_start();\r
508     k=j;\r
509     for(j=0;j<k;j++)\r
510     {\r
511        pHd[j]  =  Osal_qmssConvertDescPhyToVirt(pHd[j]);\r
512     }\r
513     t3= netapi_timing_start();\r
514     sum1 += (t2-t1);\r
515     sum2 += (t3-t2);\r
516     //raw push\r
517     t4= netapi_timing_start();\r
518     for(j=0;j<k;j++)\r
519     {\r
520        if (!pHd[j]) continue;\r
521        pHd[j]= Osal_qmssConvertDescVirtToPhy(pHd[j]);\r
522     }\r
523     t5= netapi_timing_start();\r
524     for(j=0;j<k;j++)\r
525     {\r
526       pktio_mQmssQueuePushDescSizeRaw(freeQ,\r
527                                              (void *) pHd[j],\r
528                                              128);\r
529     }\r
530     t6= netapi_timing_start();\r
531     sum3 += (t5-t4);\r
532     sum4 += (t6-t5);\r
533 \r
534     if (!abort)\r
535     printf("nt=%d raw pop=%d  p2v=%d v2p=%d raw push=%d\n", i,\r
536              sum1/k,  sum2/k, sum3/k, sum4/k);\r
537     sleep(1);\r
538 }\r
539 return;\r
540 }\r
541 \r
542 //full queue push/pops\r
543 void benchmarks3(Pktlib_HeapHandle h , int ntrials)\r
544 {\r
545 int i,j;\r
546 int k;\r
547 int abort=0;\r
548 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);\r
549 \r
550 //n_trials of NTOPOP actions\r
551 for(i=0;i<ntrials;i++)\r
552 {\r
553     abort=0;\r
554     sum2=sum4=0;\r
555     //raw pop\r
556     t1= netapi_timing_start();\r
557     for(j=0;j<NTOPOP;j++)\r
558     {\r
559        pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(Qmss_queuePop(freeQ));\r
560        if (!pHd[j])\r
561        {\r
562          printf("abort test. out of descriptors\n"); abort=1;\r
563          break;\r
564        }\r
565     }\r
566     t3= netapi_timing_start();\r
567     sum2 += (t3-t1);\r
568     k=j;\r
569     //raw push\r
570     t5= netapi_timing_start();\r
571     for(j=0;j<k;j++)\r
572     {\r
573        if (!pHd[j]) continue;\r
574        Qmss_queuePushDescSize(freeQ, pHd[j], 128);\r
575     }\r
576     t6= netapi_timing_start();\r
577     sum4 += (t6-t5);\r
578     if (!abort)\r
579     printf("nt=%d pop=%d  push=%d\n", i,\r
580               sum2/k, sum4/k);\r
581     sleep(1);\r
582 }\r
583 return;\r
584 }\r
585 \r