Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:46:54

0001 #ifndef FWCore_Framework_WorkerInPath_h
0002 #define FWCore_Framework_WorkerInPath_h
0003 
0004 /*
0005 
0006     Author: Jim Kowalkowski 28-01-06
0007 
0008 
0009     A wrapper around a Worker, so that statistics can be managed
0010     per path.  A Path holds Workers as these things.
0011 
0012 */
0013 
0014 #include "FWCore/Framework/interface/maker/Worker.h"
0015 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0016 #include "FWCore/ServiceRegistry/interface/ParentContext.h"
0017 #include "FWCore/ServiceRegistry/interface/PlaceInPathContext.h"
0018 
0019 namespace edm {
0020 
0021   class PathContext;
0022   class StreamID;
0023   class ServiceToken;
0024 
0025   class WorkerInPath {
0026   public:
0027     enum FilterAction { Normal = 0, Ignore, Veto };
0028 
0029     WorkerInPath(Worker*, FilterAction theAction, unsigned int placeInPath, bool runConcurrently);
0030 
0031     template <typename T>
0032     void runWorkerAsync(WaitingTaskHolder,
0033                         typename T::TransitionInfoType const&,
0034                         ServiceToken const&,
0035                         StreamID,
0036                         typename T::Context const*);
0037 
0038     bool checkResultsOfRunWorker(bool wasEvent);
0039 
0040     void skipWorker(EventPrincipal const& iPrincipal) { worker_->skipOnPath(iPrincipal); }
0041     void skipWorker(RunPrincipal const&) {}
0042     void skipWorker(LuminosityBlockPrincipal const&) {}
0043 
0044     void clearCounters() { timesVisited_ = timesPassed_ = timesFailed_ = timesExcept_ = 0; }
0045 
0046     int timesVisited() const { return timesVisited_; }
0047     int timesPassed() const { return timesPassed_; }
0048     int timesFailed() const { return timesFailed_; }
0049     int timesExcept() const { return timesExcept_; }
0050 
0051     FilterAction filterAction() const { return filterAction_; }
0052     Worker* getWorker() const { return worker_; }
0053     bool runConcurrently() const noexcept { return runConcurrently_; }
0054     unsigned int bitPosition() const noexcept { return placeInPathContext_.placeInPath(); }
0055 
0056     void setPathContext(PathContext const* v) { placeInPathContext_.setPathContext(v); }
0057 
0058   private:
0059     int timesVisited_;
0060     int timesPassed_;
0061     int timesFailed_;
0062     int timesExcept_;
0063 
0064     FilterAction filterAction_;
0065     Worker* worker_;
0066 
0067     PlaceInPathContext placeInPathContext_;
0068     bool runConcurrently_;
0069   };
0070 
0071   inline bool WorkerInPath::checkResultsOfRunWorker(bool wasEvent) {
0072     if (not wasEvent) {
0073       return true;
0074     }
0075     auto state = worker_->state();
0076     bool rc = true;
0077     switch (state) {
0078       case Worker::Fail: {
0079         rc = false;
0080         break;
0081       }
0082       case Worker::Pass:
0083         break;
0084       case Worker::Exception: {
0085         ++timesExcept_;
0086         return true;
0087       }
0088 
0089       default:
0090         assert(false);
0091     }
0092 
0093     if (Ignore == filterAction()) {
0094       rc = true;
0095     } else if (Veto == filterAction()) {
0096       rc = !rc;
0097     }
0098 
0099     if (rc) {
0100       ++timesPassed_;
0101     } else {
0102       ++timesFailed_;
0103     }
0104     return rc;
0105   }
0106 
0107   template <typename T>
0108   void WorkerInPath::runWorkerAsync(WaitingTaskHolder iTask,
0109                                     typename T::TransitionInfoType const& info,
0110                                     ServiceToken const& token,
0111                                     StreamID streamID,
0112                                     typename T::Context const* context) {
0113     if constexpr (T::isEvent_) {
0114       ++timesVisited_;
0115     }
0116 
0117     if constexpr (T::isEvent_) {
0118       ParentContext parentContext(&placeInPathContext_);
0119       worker_->doWorkAsync<T>(iTask, info, token, streamID, parentContext, context);
0120     } else {
0121       ParentContext parentContext(context);
0122 
0123       // We do not need to run prefetching here because this only handles
0124       // stream transitions for runs and lumis. There are no products put
0125       // into the runs or lumis in stream transitions, so there can be
0126       // no data dependencies which require prefetching. Prefetching is
0127       // needed for global transitions, but they are run elsewhere.
0128       worker_->doWorkNoPrefetchingAsync<T>(iTask, info, token, streamID, parentContext, context);
0129     }
0130   }
0131 }  // namespace edm
0132 
0133 #endif