CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/FWCore/Framework/src/Path.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Path_h
00002 #define FWCore_Framework_Path_h
00003 
00004 /*
00005   Author: Jim Kowalkowski 28-01-06
00006 
00007   An object of this type represents one path in a job configuration.
00008   It holds the assigned bit position and the list of workers that are
00009   an event must pass through when this parh is processed.  The workers
00010   are held in WorkerInPath wrappers so that per path execution statistics
00011   can be kept for each worker.
00012 */
00013 
00014 #include "FWCore/Framework/interface/CurrentProcessingContext.h"
00015 #include "FWCore/Framework/src/WorkerInPath.h"
00016 #include "FWCore/Framework/src/Worker.h"
00017 #include "DataFormats/Common/interface/HLTenums.h"
00018 #include "DataFormats/Common/interface/TriggerResults.h"
00019 
00020 #include "boost/shared_ptr.hpp"
00021 
00022 #include <string>
00023 #include <vector>
00024 
00025 #include "FWCore/Framework/src/RunStopwatch.h"
00026 
00027 namespace edm {
00028 
00029   class Path {
00030   public:
00031     typedef hlt::HLTState State;
00032 
00033     typedef std::vector<WorkerInPath> WorkersInPath;
00034     typedef WorkersInPath::size_type        size_type;
00035     typedef boost::shared_ptr<HLTGlobalStatus> TrigResPtr;
00036 
00037     Path(int bitpos, std::string const& path_name,
00038          WorkersInPath const& workers,
00039          TrigResPtr trptr,
00040          ActionTable const& actions,
00041          boost::shared_ptr<ActivityRegistry> reg,
00042          bool isEndPath);
00043 
00044     template <typename T>
00045     void processOneOccurrence(typename T::MyPrincipal&, EventSetup const&);
00046 
00047     int bitPosition() const { return bitpos_; }
00048     std::string const& name() const { return name_; }
00049 
00050     std::pair<double, double> timeCpuReal() const {
00051       if(stopwatch_) {
00052         return std::pair<double, double>(stopwatch_->cpuTime(), stopwatch_->realTime());
00053       }
00054       return std::pair<double, double>(0., 0.);
00055     }
00056 
00057     std::pair<double, double> timeCpuReal(unsigned int const i) const {
00058       return workers_.at(i).timeCpuReal();
00059     }
00060 
00061     void clearCounters();
00062 
00063     int timesRun() const { return timesRun_; }
00064     int timesPassed() const { return timesPassed_; }
00065     int timesFailed() const { return timesFailed_; }
00066     int timesExcept() const { return timesExcept_; }
00067     //int abortWorker() const { return abortWorker_; }
00068     State state() const { return state_; }
00069 
00070     size_type size() const { return workers_.size(); }
00071     int timesVisited(size_type i) const { return workers_.at(i).timesVisited(); }
00072     int timesPassed (size_type i) const { return workers_.at(i).timesPassed() ; }
00073     int timesFailed (size_type i) const { return workers_.at(i).timesFailed() ; }
00074     int timesExcept (size_type i) const { return workers_.at(i).timesExcept() ; }
00075     Worker const* getWorker(size_type i) const { return workers_.at(i).getWorker(); }
00076 
00077     void useStopwatch();
00078   private:
00079     RunStopwatch::StopwatchPointer stopwatch_;
00080     int timesRun_;
00081     int timesPassed_;
00082     int timesFailed_;
00083     int timesExcept_;
00084     //int abortWorker_;
00085     State state_;
00086 
00087     int bitpos_;
00088     std::string name_;
00089     TrigResPtr trptr_;
00090     boost::shared_ptr<ActivityRegistry> actReg_;
00091     ActionTable const* act_table_;
00092 
00093     WorkersInPath workers_;
00094 
00095     bool isEndPath_;
00096 
00097     // Helper functions
00098     // nwrwue = numWorkersRunWithoutUnhandledException (really!)
00099     bool handleWorkerFailure(cms::Exception const& e, int nwrwue, bool isEvent);
00100     void recordUnknownException(int nwrwue, bool isEvent);
00101     void recordStatus(int nwrwue, bool isEvent);
00102     void updateCounters(bool succeed, bool isEvent);
00103   };
00104 
00105   namespace {
00106     template <typename T>
00107     class PathSignalSentry {
00108     public:
00109       PathSignalSentry(ActivityRegistry *a,
00110                        std::string const& name,
00111                        int const& nwrwue,
00112                        hlt::HLTState const& state) :
00113       a_(a), name_(name), nwrwue_(nwrwue), state_(state) {
00114         if (a_) T::prePathSignal(a_, name_);
00115       }
00116       ~PathSignalSentry() {
00117         HLTPathStatus status(state_, nwrwue_);
00118         if(a_) T::postPathSignal(a_, name_, status);
00119       }
00120     private:
00121       ActivityRegistry* a_;
00122       std::string const& name_;
00123       int const& nwrwue_;
00124       hlt::HLTState const& state_;
00125     };
00126   }
00127 
00128   template <typename T>
00129   void Path::processOneOccurrence(typename T::MyPrincipal& ep, EventSetup const& es) {
00130 
00131     //Create the PathSignalSentry before the RunStopwatch so that
00132     // we only record the time spent in the path not from the signal
00133     int nwrwue = -1;
00134     std::auto_ptr<PathSignalSentry<T> > signaler(new PathSignalSentry<T>(actReg_.get(), name_, nwrwue, state_));
00135 
00136     // A RunStopwatch, but only if we are processing an event.
00137     RunStopwatch stopwatch(T::isEvent_ ? stopwatch_ : RunStopwatch::StopwatchPointer());
00138 
00139     if (T::isEvent_) {
00140       ++timesRun_;
00141     }
00142     state_ = hlt::Ready;
00143 
00144     // nwrue =  numWorkersRunWithoutUnhandledException
00145     bool should_continue = true;
00146     CurrentProcessingContext cpc(&name_, bitPosition(), isEndPath_);
00147 
00148     WorkersInPath::size_type idx = 0;
00149     // It seems likely that 'nwrwue' and 'idx' can never differ ---
00150     // if so, we should remove one of them!.
00151     for (WorkersInPath::iterator i = workers_.begin(), end = workers_.end();
00152           i != end && should_continue;
00153           ++i, ++idx) {
00154       ++nwrwue;
00155       assert (static_cast<int>(idx) == nwrwue);
00156       try {
00157         cpc.activate(idx, i->getWorker()->descPtr());
00158         should_continue = i->runWorker<T>(ep, es, &cpc);
00159       }
00160       catch(cms::Exception& e) {
00161         // handleWorkerFailure may throw a new exception.
00162         should_continue = handleWorkerFailure(e, nwrwue, T::isEvent_);
00163       }
00164       catch(...) {
00165         recordUnknownException(nwrwue, T::isEvent_);
00166         throw;
00167       }
00168     }
00169     updateCounters(should_continue, T::isEvent_);
00170     recordStatus(nwrwue, T::isEvent_);
00171   }
00172 
00173 }
00174 
00175 #endif