zoukankan      html  css  js  c++  java
  • 如何找到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!!
  • 相关阅读:
    多线程系列 线程池ThreadPool
    多线程系列 使用多线程的安全问题
    C#反射Assembly 详细说明
    Assembly(c#中简单说明[转]
    反射调用性能比较
    MFC控件GDI编程
    MFC控件第一讲.DC编程
    MFC原理第六讲.消息传递
    MFC原理第五讲.消息映射.以及如何添加消息
    MFC原理第四讲.动态创建机制
  • 原文地址:https://www.cnblogs.com/zengtx/p/6421581.html
Copyright © 2011-2022 走看看