Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:20

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::atomic<int> threadID{-1};
0042   std::vector<std::thread> threads;
0043 
0044   TThread::Initialize();
0045   //When threading, also have to keep ROOT from logging all TObjects into a list
0046   TObject::SetObjectStat(false);
0047 
0048   //Have to avoid having Streamers modify themselves after they have been used
0049   TVirtualStreamerInfo::Optimize(false);
0050 
0051   std::string const cut(" pt >= 1 & momentum().x() > 0.5 & quality('highPurity') ");
0052   StringCutObjectSelector<reco::Track> selectShared(cut, false);
0053   StringCutObjectSelector<reco::Track> selectSharedLazy(cut, true);
0054   for (int i = 0; i < kNThreads; ++i) {
0055     threads.emplace_back([&canStart, &canStartEval, &failed, &selectShared, &selectSharedLazy, &threadID]() {
0056       auto id = ++threadID;
0057       bool sharedTestShouldSucceed = ((id % 2) == 0);
0058       try {
0059         static thread_local TThread guard;
0060         reco::Track trk(20.,
0061                         20.,
0062                         reco::Track::Point(),
0063                         reco::Track::Vector(sharedTestShouldSucceed ? 1. : 0., 1., 1.),
0064                         +1,
0065                         reco::Track::CovarianceMatrix{});
0066         trk.setQuality(reco::Track::highPurity);
0067         std::string const cut(" pt >= 1 & quality('highPurity') ");
0068         //std::cout <<cut<<std::endl;
0069         bool const lazy = true;
0070 
0071         --canStart;
0072         while (canStart > 0) {
0073         }
0074 
0075         //need to make sure canStartEval is decremented even if we have an exception
0076         Decrementer decCanStartEval(canStartEval);
0077 
0078         StringCutObjectSelector<reco::Track> select(cut, lazy);
0079 
0080         decCanStartEval.decrement();
0081 
0082         while (canStartEval > 0) {
0083         }
0084         if (not select(trk)) {
0085           std::cout << "selection failed" << std::endl;
0086           failed = true;
0087         }
0088         if (sharedTestShouldSucceed != selectShared(trk)) {
0089           std::cout << "selection shared failed, expected " << sharedTestShouldSucceed << std::endl;
0090           failed = true;
0091         }
0092         if (sharedTestShouldSucceed != selectSharedLazy(trk)) {
0093           std::cout << "selection shared lazy failed, expected " << sharedTestShouldSucceed << std::endl;
0094           failed = true;
0095         }
0096       } catch (cms::Exception const& exception) {
0097         std::cout << exception.what() << std::endl;
0098         failed = true;
0099       }
0100     });
0101   }
0102   canStart = true;
0103 
0104   for (auto& thread : threads) {
0105     thread.join();
0106   }
0107 
0108   if (failed) {
0109     std::cout << "FAILED" << std::endl;
0110     return 1;
0111   }
0112 
0113   std::cout << "OK" << std::endl;
0114   return 0;
0115 }