Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:17

0001 #include "CommonTools/Utils/interface/cutParser.h"
0002 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0003 #include "DataFormats/TrackReco/interface/Track.h"
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 
0006 #include "TThread.h"
0007 #include "TObject.h"
0008 #include "TVirtualStreamerInfo.h"
0009 
0010 #include <thread>
0011 #include <atomic>
0012 #include <iostream>
0013 #include <string>
0014 
0015 namespace {
0016   class Decrementer {
0017   public:
0018     Decrementer(std::atomic<int>& iValue) : value_(iValue), dec_(true) {}
0019     ~Decrementer() {
0020       if (dec_) {
0021         --value_;
0022       }
0023     }
0024 
0025     void decrement() {
0026       --value_;
0027       dec_ = false;
0028     }
0029 
0030   private:
0031     std::atomic<int>& value_;
0032     bool dec_;
0033   };
0034 }  // namespace
0035 
0036 int main() {
0037   constexpr int kNThreads = 30;
0038   std::atomic<int> canStart{kNThreads};
0039   std::atomic<int> canStartEval{kNThreads};
0040   std::atomic<bool> failed{false};
0041   std::vector<std::thread> threads;
0042 
0043   TThread::Initialize();
0044   //When threading, also have to keep ROOT from logging all TObjects into a list
0045   TObject::SetObjectStat(false);
0046 
0047   //Have to avoid having Streamers modify themselves after they have been used
0048   TVirtualStreamerInfo::Optimize(false);
0049 
0050   for (int i = 0; i < kNThreads; ++i) {
0051     threads.emplace_back([&canStart, &canStartEval, &failed]() {
0052       try {
0053         static thread_local TThread guard;
0054         reco::Track trk(
0055             20., 20., reco::Track::Point(), reco::Track::Vector(1., 1., 1.), +1, reco::Track::CovarianceMatrix{});
0056         trk.setQuality(reco::Track::highPurity);
0057         std::string const cut(" pt >= 1 & quality('highPurity') ");
0058         //std::cout <<cut<<std::endl;
0059         bool const lazy = true;
0060 
0061         --canStart;
0062         while (canStart > 0) {
0063         }
0064 
0065         //need to make sure canStartEval is decremented even if we have an exception
0066         Decrementer decCanStartEval(canStartEval);
0067 
0068         StringCutObjectSelector<reco::Track> select(cut, lazy);
0069 
0070         decCanStartEval.decrement();
0071 
0072         while (canStartEval > 0) {
0073         }
0074         if (not select(trk)) {
0075           std::cout << "selection failed" << std::endl;
0076           failed = true;
0077         }
0078       } catch (cms::Exception const& exception) {
0079         std::cout << exception.what() << std::endl;
0080         failed = true;
0081       }
0082     });
0083   }
0084   canStart = true;
0085 
0086   for (auto& thread : threads) {
0087     thread.join();
0088   }
0089 
0090   if (failed) {
0091     std::cout << "FAILED" << std::endl;
0092     return 1;
0093   }
0094 
0095   std::cout << "OK" << std::endl;
0096   return 0;
0097 }