crateThread.cxx

00001 #include <iostream>                 // XXX This is for debug only!
00002 
00003 #include "RodCrate/RodModule.h"
00004 #include "RodCrate/BocCard.h"
00005 #include "RodCrate/TimModule.h"              // For TimMaskFrequency
00006 
00007 #include "crateImpl.h"
00008 #include "primListWrapper.h"
00009 
00010 namespace SctApi {
00011 #if USE_THREADS
00012   void CrateImpl::pollingLoop() {
00013     std::cout << "POLL: Starting Polling loop\n";
00014 
00015     // Tell RODs not to send their own primitive lists
00016     bool synchRods = false;
00017     // Which RODs are waiting for a new primitive lists
00018     int synched = 0;
00019 
00020     int waitCount = 0;
00021 
00022     // Loop over all RODs 
00023     while(!m_stopPolling) {
00024 //       std::cout << "POLL: Start of loop\n";
00025       if(!m_enablePolling) {
00026         do {
00027           usleep(1000);
00028         } while(!m_enablePolling);
00029       }
00030 
00031       // This mask is rebuilt on each iteration (just in case someone removes a ROD on the fly...)
00032       int rodMask = 0;
00033       // Count how many RODs were polled
00034       int rods = 0;
00035 
00036       // Theres a primlist to go to all RODs
00037 #warning "This takes priority over all other lists..."
00038       // First wait for RODs to finish their previous lists
00039       {
00040         boost::mutex::scoped_lock lock(primQueue_mutex);
00041         if(listQueueAll.size() > 0) {
00042 //           std::cout << "Have new all primitive\n";
00043           if(synchRods == false) {
00044             synchRods = true;
00045             synched = 0;
00046 //             std::cout << "Synching RODs for all primitive\n";
00047           }
00048         }
00049       }
00050 
00051       // For each rod:
00052       for(RodMap::iterator i=rodMap.begin();i!=rodMap.end();i++){
00053         SctPixelRod::RodModule &rod = *(i->second.second);
00054         RodStatus &status = *(i->second.first);
00055         //   Get locks
00056         {
00057           boost::mutex::scoped_lock statLock(status.mutex);
00058           SctPixelRod::PrimState oldPrimState = rod.getPrimState();
00059 
00060           try {
00061             boost::mutex::scoped_lock lock(vmeMutex);
00062             //   PrimHandler
00063             rod.primHandler();
00064           } catch (SctPixelRod::BaseException &ex) {
00065             std::cerr << "Exception in polling loop (prim handler): " << ex << std::endl;
00066 #warning "Should do something here!"
00067           } catch (...) {
00068             std::cerr << "Unknown exception in polling loop (prim handler)\n";
00069 #warning "Should do something here!"
00070           } // Keep VME lock for duration of try
00071 
00072 //             std::cout << "POLL: PrimHandler state " << rod.getPrimState() << "\n" ;
00073 //             std::cout << "POLL: Mystate " << status.currState << "\n" ;
00074 //             std::cout << "POLL: Queue size " << status.listQueue.size() << "\n" ;
00075           SctPixelRod::PrimState newPState = rod.getPrimState();
00076 
00077           if((newPState == SctPixelRod::PRIM_IDLE || newPState == SctPixelRod::PRIM_WAITING)) {
00078             if(synchRods) {
00079               // This ROD is waiting for the all ROD list
00080               synched |= 1 << i->first;
00081 
00082 //               std::cout << "ROD " << i->first << " ready for All primitive\n";
00083             } else if(status.currState == MYPRIM_STATE_LOADED) {
00084               boost::shared_ptr<PrimListWrapper> nextPrimList;
00085               {
00086                 boost::mutex::scoped_lock lock(primQueue_mutex);
00087                 if(status.listQueue.size() > 0) {
00088                   // Send list from personal queue
00089                   nextPrimList = status.listQueue.front();
00090                   status.listQueue.pop_front();
00091                 }
00092               }
00093 
00094               if(nextPrimList) {
00095                 try {
00096                   boost::mutex::scoped_lock lock(vmeMutex);
00097 
00098                   rod.sendPrimList(nextPrimList->list.get());   // Pass in auto_ptr (only used briefly)
00099                 } catch (SctPixelRod::BaseException &ex) {
00100                   std::cerr << "Exception in polling loop (send prim list): " << ex << std::endl;
00101 #warning "Should do something here!"
00102                 } catch(...) {
00103                   std::cerr << "Unknown exception in polling loop (send prim list)\n";
00104 #warning "Should do something here!"
00105                 }
00106               }
00107             } else {
00108               // No new prim lists
00109             }
00110           }
00111 
00112           if(oldPrimState != newPState) {
00113             //               std::cout << "New primHandler state " << newPState << "\n" ;
00114 
00115             // Just entered new state...
00116             switch(newPState) {
00117             case SctPixelRod::PRIM_LOADED:
00118             case SctPixelRod::PRIM_EXECUTING:
00119               status.currState = MYPRIM_STATE_EXECUTING;
00120 //               std::cout << "POLL: STATE: Changing state to executing\n";
00121               break;
00122             case SctPixelRod::PRIM_IDLE:
00123             case SctPixelRod::PRIM_WAITING:
00124               status.currState = MYPRIM_STATE_COMPLETE;
00125 //               std::cout << "POLL: STATE: Change state to COMPLETE\n";
00126               break;
00127             case SctPixelRod::PRIM_PAUSED:
00128               break;
00129             }
00130           }
00131 
00132           try {
00133             boost::mutex::scoped_lock lock(vmeMutex);
00134             //   TextHandler
00135             SctPixelRod::TextBuffState newTState = rod.textHandler();
00136 
00137             while (newTState == SctPixelRod::TEXT_RQ_SET) {
00138               doTextBuffer(rod);
00139               // Text State now TEXT_IDLE
00140               // Needs checking for more text buffers
00141               newTState = rod.textHandler();
00142             }
00143           } catch (SctPixelRod::BaseException &ex) {
00144             std::cerr << "Exception in polling loop (text handler): " << ex << std::endl;
00145 #warning "Should do something here!"
00146           } catch (...) {
00147             std::cerr << "Unknown exception in polling loop (text handler)\n";
00148 #warning "Should do something here!"
00149           }
00150 //           status.currState = rod.getPrimState();
00151         }        // Give status lock
00152 
00153         // Don't do when have any locks...
00154         sched_yield();
00155 
00156         rods ++;
00157         rodMask |= 1 << i->first;
00158       }         // Next ROD
00159 
00160 //       std::cout << "Polled " << rods << " RODs\n";
00161 
00162       // All RODs are ready for the list
00163       if(synchRods && synched == rodMask) {
00164 //         std::cout << "All primitive condition met\n";
00165 
00166         boost::shared_ptr<PrimListWrapper> globalPrimList;
00167         {
00168           boost::mutex::scoped_lock lock(primQueue_mutex);
00169           globalPrimList = listQueueAll.front();
00170           listQueueAll.pop_front();
00171         }
00172 
00173         if(globalPrimList) {
00174           // For each rod:
00175           for(RodMap::iterator i=rodMap.begin();i!=rodMap.end();i++){
00176             SctPixelRod::RodModule &rod = *(i->second.second);
00177 
00178 //             std::cout << "Adding All primitive to ROD " << i->first << std::endl;
00179 
00180             RodStatus &status = *(i->second.first);
00181             //   Get locks
00182             {
00183               boost::mutex::scoped_lock statLock(status.mutex);
00184               try {
00185                 boost::mutex::scoped_lock lock(vmeMutex);
00186 
00187                 rod.sendPrimList(globalPrimList->list.get());   // Pass in pointer (only used briefly)
00188 
00189 //                 std::cerr << "POLL: Sending all primitive to " << i->first << "\n";
00190 
00191                 // So it executes it next time around
00192                 status.currState = MYPRIM_STATE_LOADED;
00193               } catch (SctPixelRod::BaseException &ex) {
00194                 std::cerr << "Exception in polling loop (global send prim list): " << ex << std::endl;
00195 #warning "Should do something here!"
00196               } catch (...) {
00197                 std::cerr << "Unknown exception in polling loop (global send prim list)\n";
00198 #warning "Should do something here!"
00199               }
00200             }
00201           }
00202         }
00203 
00204         // Sent primlist
00205         synchRods = false;
00206       }
00207 
00208       if(m_stopPolling) {
00209         // Stop thread
00210         break;
00211       }
00212 
00213       {
00214         // Make sure nobody adds to the queues while they're being checked!
00215         boost::mutex::scoped_lock lock(primQueue_mutex);
00216 
00217         bool doWait = true;
00218 
00219         // Check if RODs are idle
00220         for(RodMap::iterator i=rodMap.begin();i!=rodMap.end();i++){
00221           // SctPixelRod::RodModule &rod = *(i->second.second);
00222           RodStatus &status = *(i->second.first);
00223 
00224           if(status.currState == MYPRIM_STATE_COMPLETE) {
00225             if(status.listQueue.size() !=  0) {
00226               // Queue not empty
00227               doWait = false;
00228               break; // The for loop
00229             }
00230           } else {
00231             // Prim still executing
00232             doWait = false;
00233             break; // The for loop
00234           }
00235         }
00236 
00237         // Don't be too eager to block as there may be text buffers arriving...
00238         if(doWait) {
00239 //           std::cout << "POLL: Wait\n";
00240           waitCount ++;
00241           if(waitCount>5) {
00242             usleep(10);
00243           } else if(waitCount>10) {
00244             usleep(100);
00245           } else if(waitCount>20) {
00246             sleep(1);
00247 //           } else if(waitCount>20) {
00248 //             if(listQueueAll.size() == 0) {
00249 //               std::cout << "Polling loop blocking\n";
00250 //               primQueue_notEmpty.wait(lock);
00251 //               waitCount = 0;
00252 //             }
00253           }
00254         }
00255       }
00256 
00257       //      usleep(1000);
00258 
00259 //       std::cout << "Polling loop looping\n";
00260     }  // While (1)
00261   }
00262 #endif
00263 }

Generated on Mon Feb 6 14:01:18 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6