Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:40

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 
0006 #include <sys/time.h>
0007 #include <sys/resource.h>
0008          
0009 #include <iostream>
0010 #include <fstream>
0011 #include <mutex>
0012 using namespace std;
0013 
0014 #include <TTree.h>
0015 #include <TFile.h>
0016 
0017 #include "JEventProcessorJANARATE.h"
0018 
0019 TFile *rootfile = nullptr;
0020 mutex mtxroot;
0021 
0022 // Routine used to allow us to register our JEventSourceGenerator
0023 extern "C"{
0024 void InitPlugin(JApplication *app){
0025     InitJANAPlugin(app);
0026     app->Add(new JEventProcessorJANARATE(app));
0027 }
0028 } // "C"
0029 
0030 //------------------------------------------------------------------
0031 // Init
0032 //------------------------------------------------------------------
0033 void JEventProcessorJANARATE::Init(void)
0034 {
0035 //  // Initialize our mutex
0036 //  pthread_mutex_init(&mutex, NULL);
0037     
0038 //  initialized = false;
0039     finalized = false;
0040     Ncalls = 0;
0041     prescale = 100;
0042 
0043     GetApplication()->GetJParameterManager()->SetDefaultParameter(
0044         "RATE:PRESCALE", 
0045         prescale, 
0046         "Prescale entries in rate tree by this");
0047     
0048     getitimer(ITIMER_REAL, &start_tmr);
0049     if(start_tmr.it_value.tv_sec==0 && start_tmr.it_value.tv_usec==0){
0050         struct itimerval value, ovalue;
0051         value.it_interval.tv_sec = 0;
0052         value.it_interval.tv_usec = 0;
0053         value.it_value.tv_sec = 1000000;
0054         value.it_value.tv_usec = 0;
0055         setitimer(ITIMER_REAL, &value, &ovalue);
0056 
0057         getitimer(ITIMER_REAL, &start_tmr);
0058     }
0059 
0060     lock_guard<std::mutex> lck(mtxroot);
0061     rootfile = new TFile("janarate.root", "RECREATE");
0062     rate_tree = new TTree("rate_tree","Event Processing Rates");
0063     rate_tree->Branch("rates", &rate, "tot_rate/D:tot_integrated_rate:thread_rate:thread_delta_sec:cpu:mem_MB:threadid/i");
0064     rate_tree->SetMarkerStyle(20);
0065 
0066 }
0067 
0068 //------------------------------------------------------------------
0069 // Process
0070 //------------------------------------------------------------------
0071 void JEventProcessorJANARATE::Process(const std::shared_ptr<const JEvent>& aEvent)
0072 {
0073     double loadavg = 0.0;
0074 
0075     if(aEvent->GetEventNumber()%prescale != 0) return;
0076 
0077     // Get system resource usage
0078     struct rusage usage;
0079     getrusage(RUSAGE_SELF, &usage);
0080     double mem_usage = (double)(usage.ru_maxrss)/1024.0; // convert to MB
0081     
0082 #ifdef __linux__
0083     // Get CPU utilization
0084     static uint64_t last_sum3=0.0, last_sum4=0.0;
0085     FILE *fp = fopen("/proc/stat","r");
0086     if(fp){
0087         uint64_t a[4] = {0,0,0,0};
0088         fscanf(fp, "%*s %ld %ld %ld %ld", &a[0], &a[1], &a[2], &a[3]);
0089         fclose(fp);
0090 
0091         uint64_t sum3 = a[0] + a[1] + a[2];
0092         uint64_t sum4 = sum3 + a[3];
0093         if(last_sum4!=0) loadavg = ((double)(sum3 - last_sum3))/((double)(sum4 - last_sum4));
0094         last_sum3 = sum3;
0095         last_sum4 = sum4;
0096     }
0097 #endif // __linux__
0098 
0099 #ifdef __APPLE__
0100     // Getting CPU utilization on Mac OS X doesn't seem trivial from
0101     // a quick web search so we don't implement it here yet.
0102 #endif // __APPLE__
0103 
0104     // Fill local variable outside mutex lock in case
0105     rate_t myrate;
0106     auto app = GetApplication();
0107     myrate.tot_rate = app->GetInstantaneousRate();
0108     myrate.tot_integrated_rate = app->GetIntegratedRate();
0109 //  myrate.thread_rate = loop->GetInstantaneousRate(); // only updated every 2 seconds!
0110 //  myrate.thread_delta_sec = loop->GetLastEventProcessingTime(); // updated every event
0111 //  myrate.threadid = (unsigned int)(0xFFFFFFFF & (unsigned int)&(std::this_thread::get_id()));
0112     myrate.cpu = loadavg;
0113     myrate.mem_MB = mem_usage;
0114     
0115     lock_guard<std::mutex> lck(mtxroot);
0116     this->rate = myrate;
0117     rate_tree->Fill();
0118     Ncalls++; // do this in ROOT mutex lock just to make sure one thread updates it at a time
0119 }
0120 
0121 //------------------------------------------------------------------
0122 // Finish
0123 //------------------------------------------------------------------
0124 void JEventProcessorJANARATE::Finish(void)
0125 {
0126     // Record ending time (if necessary)
0127     if(!finalized){
0128         finalized = true;
0129 
0130         getitimer(ITIMER_REAL, &end_tmr);   
0131     }
0132 
0133     cout<<"Start time:"<<endl;
0134     cout<<"    sec="<<start_tmr.it_value.tv_sec<<endl;
0135     cout<<"   usec="<<start_tmr.it_value.tv_usec<<endl;
0136     cout<<endl;
0137     cout<<"End time:"<<endl;
0138     cout<<"    sec="<<end_tmr.it_value.tv_sec<<endl;
0139     cout<<"   usec="<<end_tmr.it_value.tv_usec<<endl;
0140     cout<<endl;
0141 
0142     double start_sec = (double)start_tmr.it_value.tv_sec + (double)start_tmr.it_value.tv_usec/1.0E6;
0143     double end_sec = (double)end_tmr.it_value.tv_sec + (double)end_tmr.it_value.tv_usec/1.0E6;
0144     double delta_sec = start_sec - end_sec;
0145     double rate = (double)Ncalls/delta_sec;
0146     
0147     cout<<"Elapsed time:"<<delta_sec<<" sec"<<endl;
0148     cout<<"Total events:"<<Ncalls<<endl;
0149     cout<<"Avg. rate (janarate):"<<rate<<" Hz"<<endl;
0150     cout<<"Avg. rate (JApplication):"<<GetApplication()->GetIntegratedRate()<<" Hz"<<endl;
0151 
0152     rootfile->Write();
0153     delete rootfile;
0154 }
0155