CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/ResourceBroker/src/FUResource.cc

Go to the documentation of this file.
00001 
00002 //
00003 // FUResource
00004 // ----------
00005 //
00006 //            12/10/2006 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
00007 //            20/01/2012 Andrei Spataru <aspataru@cern.ch>
00009 
00010 #include "EventFilter/ResourceBroker/interface/FUResource.h"
00011 #include "EventFilter/ResourceBroker/interface/ResourceChecker.h"
00012 
00013 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00014 #include "interface/shared/i2oXFunctionCodes.h"
00015 #include "interface/evb/i2oEVBMsgs.h"
00016 #include "EvffedFillerRB.h"
00017 #include "toolbox/mem/Reference.h"
00018 #include "xcept/tools.h"
00019 
00020 #include <sstream>
00021 #include <sys/shm.h>
00022 
00023 using namespace std;
00024 using namespace evf;
00025 
00026 //#define DEBUG_FU_RES
00027 
00028 
00030 // initialize static members
00032 
00033 //______________________________________________________________________________
00034 bool FUResource::doFedIdCheck_ = true;
00035 bool FUResource::useEvmBoard_ = true;
00036 unsigned int FUResource::gtpEvmId_ = FEDNumbering::MINTriggerGTPFEDID;
00037 unsigned int FUResource::gtpDaqId_ = FEDNumbering::MAXTriggerGTPFEDID;
00038 unsigned int FUResource::gtpeId_ = FEDNumbering::MINTriggerEGTPFEDID;
00039 
00041 // construction/destruction
00043 
00044 //______________________________________________________________________________
00045 FUResource::FUResource(UInt_t fuResourceId, log4cplus::Logger logger,
00046                 EvffedFillerRB *frb, xdaq::Application *app) :
00047         log_(logger), fuResourceId_(fuResourceId), superFragHead_(0),
00048                         superFragTail_(0), nbBytes_(0), superFragSize_(0), shmCell_(0),
00049                         frb_(frb), app_(app), nextEventWillHaveCRCError_(false) {
00050         //release();
00051 }
00052 
00053 //______________________________________________________________________________
00054 FUResource::~FUResource() {
00055 
00056 }
00057 
00059 // implementation of member functions
00061 
00062 //______________________________________________________________________________
00063 void FUResource::allocate(FUShmRawCell* shmCell) {
00064         //release();
00065         shmCell_ = shmCell;
00066         shmCell_->clear();
00067         shmCell_->setFuResourceId(fuResourceId_);
00068         //UPDATED
00069         shmCell_->setEventTypeData();
00070         eventPayloadSize_ = shmCell_->payloadSize();
00071         nFedMax_ = shmCell_->nFed();
00072         nSuperFragMax_ = shmCell_->nSuperFrag();
00073         /*
00074          cout << "shmCell = " << shmCell_ << " shm cell furesourceId = "
00075          << fuResourceId_ << " payload size = " << shmCell_->payloadSize()
00076          << " nFed max = " << shmCell_->nFed() << " nSuperFragMax_ = "
00077          << shmCell_->nSuperFrag() << endl;
00078          */
00079 }
00080 
00081 //______________________________________________________________________________
00082 void FUResource::release(bool detachResource) {
00083         doCrcCheck_ = false;
00084         fatalError_ = false;
00085 
00086         buResourceId_ = 0xffffffff;
00087         evtNumber_ = 0xffffffff;
00088 
00089         if (0 != superFragHead_) {
00090                 try {
00091                         superFragHead_->release();
00092                 } catch (xcept::Exception& e) {
00093                         LOG4CPLUS_ERROR(
00094                                         log_,
00095                                         "Failed to release superFragHead: "
00096                                                         << xcept::stdformat_exception_history(e));
00097                 }
00098         }
00099 
00100         superFragHead_ = 0;
00101         superFragTail_ = 0;
00102 
00103         iBlock_ = 0;
00104         nBlock_ = 0xffffffff;
00105         iSuperFrag_ = 0;
00106         nSuperFrag_ = 0xffffffff;
00107 
00108         nbSent_ = 0;
00109 
00110         nbErrors_ = 0;
00111         nbCrcErrors_ = 0;
00112 
00113         for (UInt_t i = 0; i < 1024; i++)
00114                 fedSize_[i] = 0;
00115         eventSize_ = 0;
00116 
00117         if (0 != shmCell_) {
00118                 shmCell_ = 0;
00119                 if (detachResource)
00120                         shmdt(shmCell_);
00121         }
00122 
00123 }
00124 
00125 //______________________________________________________________________________
00126 void FUResource::process(MemRef_t* bufRef) {
00127         if (fatalError()) {
00128                 LOG4CPLUS_ERROR(log_, "THIS SHOULD *NEVER* HAPPEN!."); // DEBUG
00129                 bufRef->release();
00130                 return;
00131         }
00132 #ifdef DEBUG_FU_RES
00133         std::cout << "Started process() for bufRef: " << bufRef<< std::endl;
00134 #endif
00135         MemRef_t* itBufRef = bufRef;
00136         while (0 != itBufRef && !fatalError()) {
00137                 MemRef_t* next = itBufRef->getNextReference();
00138                 itBufRef->setNextReference(0);
00139                 try {
00140 
00141                         ResourceChecker resCheck(this);
00142                         resCheck.processDataBlock(itBufRef);
00143 
00144                 } catch (xcept::Exception& e) {
00145                         LOG4CPLUS_ERROR(log_,
00146                                         "EVENT LOST:" << xcept::stdformat_exception_history(e));
00147                         fatalError_ = true;
00148                         itBufRef->setNextReference(next);
00149                 }
00150 
00151                 itBufRef = next;
00152         }
00153         if (isComplete()) {
00154                 frb_->putHeader(evtNumber_, 0);
00155                 frb_->putTrailer();
00156                 fedSize_[frb_->fedId()] = frb_->size();
00157                 UChar_t *startPos = shmCell_->writeData(frb_->getPayload(),
00158                                 frb_->size());
00159                 superFragSize_ = frb_->size();
00160                 if (!shmCell_->markSuperFrag(iSuperFrag_, superFragSize_, startPos)) {
00161                         nbErrors_++;
00162                         stringstream oss;
00163                         oss << "Failed to mark super fragment in shared mem buffer."
00164                                         << " fuResourceId:" << fuResourceId_ << " evtNumber:"
00165                                         << evtNumber_ << " iSuperFrag:" << iSuperFrag_;
00166                         XCEPT_RAISE(evf::Exception, oss.str());
00167                 }
00168 
00169                 if (!shmCell_->markFed(frb_->fedId(), frb_->size(), startPos)) {
00170                         nbErrors_++;
00171                         stringstream oss;
00172                         oss << "Failed to mark fed in buffer." << " evtNumber:"
00173                                         << evtNumber_ << " fedId:" << frb_->fedId() << " fedSize:"
00174                                         << frb_->size() << " fedAddr:0x" << hex
00175                                         << (unsigned long) frb_->getPayload() << dec;
00176                         XCEPT_RAISE(evf::Exception, oss.str());
00177                 }
00178 
00179         }
00180         return;
00181 }
00182 
00183 //______________________________________________________________________________
00184 void FUResource::appendBlockToSuperFrag(MemRef_t* bufRef) {
00185         if (0 == superFragHead_) {
00186                 superFragHead_ = bufRef;
00187                 superFragTail_ = bufRef;
00188         } else {
00189                 superFragTail_->setNextReference(bufRef);
00190                 superFragTail_ = bufRef;
00191         }
00192         return;
00193 }
00194 
00195 //______________________________________________________________________________
00196 void FUResource::removeLastAppendedBlockFromSuperFrag() {
00197         if (0 == superFragHead_) {
00198                 //nothing to do... why did we get here then ???
00199         } else if (superFragHead_ == superFragTail_) {
00200                 superFragHead_ = 0;
00201                 superFragTail_ = 0;
00202         } else {
00203                 MemRef_t *next = 0;
00204                 MemRef_t *current = superFragHead_;
00205                 while ((next = current->getNextReference()) != superFragTail_) {
00206                         current = next;
00207                         //get to the next-to-last block
00208                 }
00209                 superFragTail_ = current;
00210                 current->setNextReference(0);
00211         }
00212         return;
00213 }
00214 
00215 //______________________________________________________________________________
00216 void FUResource::superFragSize() throw (evf::Exception) {
00217         UChar_t *blockAddr = 0;
00218         UChar_t *frlHeaderAddr = 0;
00219         frlh_t *frlHeader = 0;
00220 
00221         superFragSize_ = 0;
00222 
00223         UInt_t frameSize = sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00224         MemRef_t* bufRef = superFragHead_;
00225 
00226         while (0 != bufRef) {
00227                 blockAddr = (UChar_t*) bufRef->getDataLocation();
00228                 frlHeaderAddr = blockAddr + frameSize;
00229                 frlHeader = (frlh_t*) frlHeaderAddr;
00230                 superFragSize_ += frlHeader->segsize & FRL_SEGSIZE_MASK;
00231                 bufRef = bufRef->getNextReference();
00232         }
00233 
00234         eventSize_ += superFragSize_;
00235 
00236         if (eventSize_ > eventPayloadSize_) {
00237                 nbErrors_++;
00238                 stringstream oss;
00239                 oss << "Event size exceeds maximum size." << " fuResourceId:"
00240                                 << fuResourceId_ << " evtNumber:" << evtNumber_
00241                                 << " iSuperFrag:" << iSuperFrag_ << " eventSize:" << eventSize_
00242                                 << " eventPayloadSize:" << eventPayloadSize_;
00243                 XCEPT_RAISE(evf::Exception, oss.str());
00244         }
00245 }
00246 
00247 //______________________________________________________________________________
00248 void FUResource::fillSuperFragPayload() throw (evf::Exception) {
00249         UChar_t *blockAddr = 0;
00250         UChar_t *frlHeaderAddr = 0;
00251         UChar_t *fedAddr = 0;
00252         UInt_t nbBytes = 0;
00253         UInt_t nbBytesTot = 0;
00254         frlh_t *frlHeader = 0;
00255         UChar_t *bufferPos = 0;
00256         UChar_t *startPos = 0;
00257 
00258         MemRef_t* bufRef = superFragHead_;
00259         while (bufRef != 0) {
00260                 blockAddr = (UChar_t*) bufRef->getDataLocation();
00261                 frlHeaderAddr = blockAddr + sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00262                 fedAddr = frlHeaderAddr + sizeof(frlh_t);
00263                 frlHeader = (frlh_t*) frlHeaderAddr;
00264                 nbBytes = frlHeader->segsize & FRL_SEGSIZE_MASK;
00265                 nbBytesTot += nbBytes;
00266 
00267                 // check if still within limits
00268                 if (nbBytesTot > superFragSize_) {
00269                         nbErrors_++;
00270                         stringstream oss;
00271                         oss << "Reached end of buffer." << " fuResourceId:"
00272                                         << fuResourceId_ << " evtNumber:" << evtNumber_
00273                                         << " iSuperFrag:" << iSuperFrag_;
00274                         XCEPT_RAISE(evf::Exception, oss.str());
00275                 }
00276 
00277                 bufferPos = shmCell_->writeData(fedAddr, nbBytes);
00278                 if (0 == startPos)
00279                         startPos = bufferPos;
00280 
00281                 nbBytes_ += nbBytes;
00282                 bufRef = bufRef->getNextReference();
00283         }
00284 
00285         if (!shmCell_->markSuperFrag(iSuperFrag_, superFragSize_, startPos)) {
00286                 nbErrors_++;
00287                 stringstream oss;
00288                 oss << "Failed to mark super fragment in shared mem buffer."
00289                                 << " fuResourceId:" << fuResourceId_ << " evtNumber:"
00290                                 << evtNumber_ << " iSuperFrag:" << iSuperFrag_;
00291                 XCEPT_RAISE(evf::Exception, oss.str());
00292         }
00293 
00294         return;
00295 }
00296 
00297 //______________________________________________________________________________
00298 void FUResource::releaseSuperFrag() {
00299         if (0 == superFragHead_)
00300                 return;
00301         superFragHead_->release(); // throws xcept::Exception
00302         superFragHead_ = 0;
00303         superFragTail_ = 0;
00304         return;
00305 }
00306 
00307 //______________________________________________________________________________
00308 UInt_t FUResource::nbErrors(bool reset) {
00309         UInt_t result = nbErrors_;
00310         if (reset)
00311                 nbErrors_ = 0;
00312         return result;
00313 }
00314 
00315 //______________________________________________________________________________
00316 UInt_t FUResource::nbCrcErrors(bool reset) {
00317         UInt_t result = nbCrcErrors_;
00318         if (reset)
00319                 nbCrcErrors_ = 0;
00320         return result;
00321 }
00322 
00323 //______________________________________________________________________________
00324 UInt_t FUResource::nbBytes(bool reset) {
00325         UInt_t result = nbBytes_;
00326         if (reset)
00327                 nbBytes_ = 0;
00328         return result;
00329 }