File indexing completed on 2023-10-25 09:47:50
0001 #include "TFile.h"
0002 #include "TTree.h"
0003 #include "TBranch.h"
0004 #include "TClass.h"
0005 #include "TThread.h"
0006 #include "TVirtualStreamerInfo.h"
0007 #include "TList.h"
0008 #include "TMap.h"
0009 #include "TObjString.h"
0010 #include "TH1F.h"
0011
0012
0013 #include <memory>
0014 #include <cassert>
0015 #include <iostream>
0016 #include <thread>
0017 #include <atomic>
0018 #include <sstream>
0019
0020 std::atomic<bool> waitToStart{true};
0021 std::atomic<unsigned int> countdownToWrite{0};
0022
0023 void printHelp(const char* iName, int iDefaultNThreads)
0024 {
0025 std::cout << iName <<" [number of threads] [gDebug value]\n\n"
0026 <<"[number of threads] number of threads to use in test\n"
0027 <<"[gDebug value] value of gDebug to pass to ROOT (gDebug=1 is useful)\n"
0028 <<"If no arguments are given "<<iDefaultNThreads<<" threads will be used"<<std::endl;
0029 }
0030
0031 std::pair<int,int> parseOptionsForNumberOfThreadsAndgDebug(int argc, char** argv)
0032 {
0033 constexpr int kDefaultNThreads = 4;
0034 int kDefaultgDebug = gDebug;
0035 int nThreads = kDefaultNThreads;
0036 int newGDebug = kDefaultgDebug;
0037 if( argc >= 2 ) {
0038 if(strcmp("-h",argv[1]) ==0) {
0039 printHelp(argv[0],kDefaultNThreads);
0040 exit( 0 );
0041 }
0042
0043 nThreads = atoi(argv[1]);
0044 }
0045 if(argc == 3) {
0046 newGDebug = atoi(argv[2]);
0047 }
0048
0049 if( argc > 3) {
0050 printHelp(argv[0],kDefaultNThreads);
0051 exit(1);
0052 }
0053 return std::make_pair(nThreads, newGDebug) ;
0054 }
0055
0056 TList* createList() {
0057 auto returnValue = new TList();
0058
0059 for(unsigned int i=0; i<10;++i) {
0060 returnValue->Add(new TList());
0061 returnValue->Add(new TMap());
0062 returnValue->Add(new TObjString());
0063 returnValue->Add(new TH1F());
0064 returnValue->Add(new TH1D());
0065 }
0066
0067 return returnValue;
0068 }
0069
0070 int main(int argc, char** argv) {
0071
0072 auto values = parseOptionsForNumberOfThreadsAndgDebug(argc,argv);
0073
0074 const int kNThreads = values.first;
0075 countdownToWrite = kNThreads;
0076
0077 gDebug = values.second;
0078
0079
0080 TThread::Initialize();
0081
0082 TObject::SetObjectStat(false);
0083
0084 TVirtualStreamerInfo::Optimize(false);
0085
0086
0087
0088 std::vector<std::shared_ptr<std::thread>> threads;
0089 threads.reserve(kNThreads);
0090
0091
0092
0093 for(int i=0; i< kNThreads; ++i) {
0094 threads.push_back(std::make_shared<std::thread>( std::thread([i]() {
0095 static thread_local TThread s_thread_guard;
0096
0097 std::stringstream nameStream;
0098 nameStream <<"write_thread_"<<i<<".root";
0099
0100 auto theList = createList();
0101
0102 while(waitToStart) ;
0103 TFile f(nameStream.str().c_str(), "RECREATE","test");
0104
0105 auto listTree = new TTree("TheList","TheList");
0106 listTree->Branch("theList","TList",&theList);
0107
0108 --countdownToWrite;
0109 while(countdownToWrite !=0) ;
0110
0111 for(unsigned int i = 0; i<100;++i) {
0112 listTree->Fill();
0113 }
0114 f.Write();
0115 f.Close();
0116 }) ) );
0117
0118 }
0119 waitToStart = false;
0120 for(auto& t : threads) {
0121 t->join();
0122 }
0123
0124 return 0;
0125 }
0126