Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-04 05:18:46

0001 #include "TProfile.h"
0002 #include "TThread.h"
0003 #include "TObject.h"
0004 #include "TVirtualStreamerInfo.h"
0005 #include <thread>
0006 #include <memory>
0007 #include <vector>
0008 #include <atomic>
0009 #include <sstream>
0010 #include <iostream>
0011 
0012 void printHelp(const char* iName, int iDefaultNThreads) {
0013   std::cout << iName << " [number of threads] \n\n"
0014             << "If no arguments are given " << iDefaultNThreads << " threads will be used" << std::endl;
0015 }
0016 
0017 int parseOptionsForNumberOfThreads(int argc, char** argv) {
0018   constexpr int kDefaultNThreads = 4;
0019   int returnValue = kDefaultNThreads;
0020   if (argc == 2) {
0021     if (strcmp("-h", argv[1]) == 0) {
0022       printHelp(argv[0], kDefaultNThreads);
0023       exit(0);
0024     }
0025 
0026     returnValue = atoi(argv[1]);
0027   }
0028 
0029   if (argc > 2) {
0030     printHelp(argv[0], kDefaultNThreads);
0031     exit(1);
0032   }
0033   return returnValue;
0034 }
0035 
0036 int main(int argc, char** argv) {
0037   const int kNThreads = parseOptionsForNumberOfThreads(argc, argv);
0038 
0039   std::atomic<bool> canStart{false};
0040   std::vector<std::unique_ptr<TProfile>> profiles;
0041   std::vector<std::thread> threads;
0042 
0043   TH1::AddDirectory(kFALSE);
0044 
0045   TThread::Initialize();
0046   //When threading, also have to keep ROOT from logging all TObjects into a list
0047   TObject::SetObjectStat(false);
0048 
0049   //Have to avoid having Streamers modify themselves after they have been used
0050   TVirtualStreamerInfo::Optimize(false);
0051 
0052   for (int i = 0; i < kNThreads; ++i) {
0053     std::ostringstream s;
0054     profiles.push_back(std::make_unique<TProfile>(s.str().c_str(), s.str().c_str(), 100, 10, 11, 0, 10));
0055     profiles.back()->SetCanExtend(TH1::kAllAxes);
0056     auto profile = profiles.back().get();
0057     threads.emplace_back([profile, &canStart]() {
0058       static thread_local TThread guard;
0059       while (not canStart) {
0060       }
0061       for (int x = 10; x > 0; --x) {
0062         for (int y = 0; y < 20; ++y) {
0063           profile->Fill(double(x), double(y), 1.);
0064         }
0065       }
0066     });
0067   }
0068   canStart = true;
0069 
0070   for (auto& thread : threads) {
0071     thread.join();
0072   }
0073 
0074   return 0;
0075 }