如何找到bug(8): SequentialInputHandler::run()取数逻辑

404 /************************************/
405 void SequentialInputHandler::run(void)
406 /************************************/
407 {
408 
409 
410   DEBUG_TEXT(DFDB_ROSFM, 15, "SequentialInputHandler::run: Entered");
411   std::cout << "SequentialInputHandler::run: Entered" << std::endl;
412   bool busy;
413 
414   //wangl
415   /*----------------------------*/
416   std::vector<LVL1ID> l1_vec;
417   unsigned int sendSize=1;
418   l1_vec.clear() ;
419   /*----------------------------*/
420   /*while(true) {
421     DFThread::yieldOrCancel();
422     m_statistics.yield++;
423   }
424   return ;*/
425 
426   // first, erase unsyncronized RODs
427   std::vector<LVL1ID> *channel_l1ids;
428   channel_l1ids = new std::vector<LVL1ID>[m_numberOfDataChannels] ;
429   while(true) {
430     for(int chan = 0; chan < m_numberOfDataChannels; chan++) {
431       bool isReady = m_dataChannels[chan]->readyToReadout();
432       if (isReady) {
433         unsigned int FragmentL1id =  m_dataChannels[chan]->inputFragment();
434         channel_l1ids[chan].push_back(FragmentL1id) ;
435         if(areFragmentsThere(FragmentL1id)) {
436           //DEBUG_TEXT(DFDB_ROSFM, 15, "ros ready l1id: " << FragmentL1id);
437           l1_vec.push_back(FragmentL1id) ;
438           break ;
439         }
440       }
441     }
442 
443 
444     if(l1_vec.size() > 0) {
445       LVL1ID firstId = l1_vec[0] ;
446       for(int chan = 0; chan < m_numberOfDataChannels; chan++) {
447         for(int i=0; i<channel_l1ids[chan].size(); i++) {
448           LVL1ID id = channel_l1ids[chan][i] ;
449           if(id < firstId) {
450             DEBUG_TEXT(DFDB_ROSFM, 8, "release unsyncronized ROD: " << id << ", channel: " << chan);
451             m_dataChannels[chan]->releaseFragment(id) ;
452           }
453         }
454       }
455       m_outStandingEvents.clear() ; //I think this is wrong!!
456       break ;
457     }
458     DFThread::yieldOrCancel();
459   }
460   //DEBUG_TEXT(DFDB_ROSFM, 15, "deleting vector pointer .." );
461   delete [] channel_l1ids ;
462   std::cout << "InputHandler got first ROD: " << l1_vec[0] << std::endl ;
463   if( l1_vec.size() >= sendSize )
464   {
465     LVL1Message outmsg(l1_vec);
466     if(!outmsg.send(m_l2svPort)) std::cerr<<"fail send "<<std::endl;
467     l1_vec.clear();
468   }
469 
470   ////////////////////////////////
471   std::cout << "now we are going to recv data!" << std::endl;
472 
473   while(true) {
474 
475     struct timeval t0, t1 ;
476 
477     busy = true;
478 
479     while(busy) {
480       busy = false;
481 
482 
483       for(int chan = 0; chan < m_numberOfDataChannels; chan++) {
484 
485         bool isReady = m_dataChannels[chan]->readyToReadout();
486 
487         if (isReady) {
488 
489           busy = true;
490           DEBUG_TEXT(DFDB_ROSFM, 15, "SequentialInputHandler::run: Inputting data via ROL " << chan);
491           unsigned int FragmentL1id ;
492 
493           FragmentL1id =  m_dataChannels[chan]->inputFragment();
494 
495           //m_dataChannels[chan]->releaseFragment(FragmentL1id); 
496           pushL1id(FragmentL1id,chan); // zengtx
497           if(areFragmentsThere(FragmentL1id))
498           {
499             DEBUG_TEXT(DFDB_ROSFM, 15, "ros ready l1id: " << FragmentL1id);
500             l1_vec.push_back(FragmentL1id) ;
501           }
502           if( l1_vec.size() >= sendSize )
503           {
504             LVL1Message outmsg(l1_vec);
505             if(!outmsg.send(m_l2svPort)) std::cerr<<"fail send "<<std::endl;
506             l1_vec.clear();
507           }
508         }
509       }
510 
511     }
512 
513     if( l1_vec.size()>0 )
514     {
515       LVL1Message outmsg(l1_vec);
516       if(!outmsg.send(m_l2svPort)) std::cerr<<"fail send "<<std::endl;
517       l1_vec.clear();
518     }
519 
520 
521     // We have scanned all ROLs but none has data or all pages are used in the memory pool of the
522     // respective ROL. There is nothing to do. Therefore:
523     DFThread::yieldOrCancel();
524     m_statistics.yield++;
525   }
526 
527 }
528 

查看了取数逻辑,整个SequentialInputHandler::run()函数包括两个部分:

1. 同步?删掉L1id小于0的Fragment? 我的理解是取到了第一个完整的事例 第410-469行

2. 真正取数部分,第470-525行

 

同步的部分,用了一个vector数组来记录每个dataChannel取到的Fragment的L1id. 类似于:

0 1 2 3 4  
0 1 2 3 4 5
0 1        
0 1        
0          

 

以上面的表格为例:

第一行为dataChannel 1, 收了5个Fragment,

第二行为dataChannel 2, 收了6个Fragment,

第三行为dataChannel 3, 收了2个Fragment,

第四行为dataChannel 4, 收了2个Fragment,

第五行为dataChannel 5, 收了1个Fragment.

....

 

等所有通道的第一个Fragment(即L1id=0的Fragment)都收到以后,就进行了一个判断:

449           if(id < firstId) {
450             DEBUG_TEXT(DFDB_ROSFM, 8, "release unsyncronized ROD: " << id << ", channel: " << chan);
451             m_dataChannels[chan]->releaseFragment(id) ;
452           }

 

将 L1id 小于 0 的Fragment release掉,但是这在目前的取数逻辑里是不可能发生的。L1id咋可能小于0呢?

然后问题来了,干完这个同步以后,将m_outStandingEvents clear掉了,这个时候,各个通道已经收到的Fragment的计数都被清除了,后面在继续取数的过程中,判断Fragment是否到齐的逻辑就出现了问题。所以应该把这句话去掉!

444     if(l1_vec.size() > 0) {
445       LVL1ID firstId = l1_vec[0] ;
446       for(int chan = 0; chan < m_numberOfDataChannels; chan++) {
447         for(int i=0; i<channel_l1ids[chan].size(); i++) {
448           LVL1ID id = channel_l1ids[chan][i] ;
449           if(id < firstId) {
450             DEBUG_TEXT(DFDB_ROSFM, 8, "release unsyncronized ROD: " << id << ", channel: " << chan);
451             m_dataChannels[chan]->releaseFragment(id) ;
452           }
453         }
454       }
455       m_outStandingEvents.clear() ; //I think this is wrong!!

 

posted @ 2017-02-20 21:24  小荷才楼尖尖角  Views(405)  Comments(0Edit  收藏  举报