37 printf(
"TARunInfo::ctor!\n");
54 printf(
"TARunInfo::dtor!\n");
76 printf(
"TARunInfo::dtor: deleted %d queued flow events!\n", count);
94 printf(
"TAFlowEvent::ctor: chain %p\n", flow);
101 printf(
"TAFlowEvent::dtor: this %p, next %p\n",
this,
fNext);
116 printf(
"TARunObject::ctor, run %d\n", runinfo->
fRunNo);
122 printf(
"TARunObject::BeginRun, run %d\n", runinfo->
fRunNo);
128 printf(
"TARunObject::EndRun, run %d\n", runinfo->
fRunNo);
134 printf(
"TARunObject::NextSubrun, run %d\n", runinfo->
fRunNo);
140 printf(
"TARunObject::PauseRun, run %d\n", runinfo->
fRunNo);
146 printf(
"TARunObject::ResumeRun, run %d\n", runinfo->
fRunNo);
152 printf(
"TARunObject::PreEndRun, run %d\n", runinfo->
fRunNo);
158 printf(
"TARunObject::Analyze!\n");
169 printf(
"TARunObject::Analyze!\n");
180 printf(
"TARunObject::AnalyzeSpecialEvent!\n");
192 printf(
"TAFactory::Usage!\n");
198 printf(
"TAFactory::Init!\n");
204 printf(
"TAFactory::Finish!\n");
226 printf(
"TARootHelper::ctor!\n");
232 snprintf(xfilename,
sizeof(xfilename),
"output%05d.root", runinfo->
fRunNo);
250 if (status < 0 && errno == ENOENT) {
251 fprintf(stdout,
"TARootHelper::Init: creating ROOT output directory \"%s\"\n",
fgUserOutputDirectory.c_str());
254 fprintf(stderr,
"TARootHelper::ctor: Error: cannot output directory \"%s\", errno %d (%s)\n",
fgUserOutputDirectory.c_str(), errno, strerror(errno));
260 fprintf(stdout,
"TARootHelper::Init: creating ROOT output file \"%s\"\n",
fOutputFileName.c_str());
265 fprintf(stderr,
"TARootHelper::ctor: Error: cannot open output ROOT file \"%s\"\n",
fOutputFileName.c_str());
273 printf(
"TARootHelper::ctor: ROOT output file is \"%s\"!\n",
fOutputFileName.c_str());
285 printf(
"TARootHelper::dtor!\n");
292 printf(
"TARootHelper::dtor: ROOT output file closed!\n");
305#ifdef HAVE_THTTP_SERVER
308#include "THttpServer.h"
311static void jsroot_ReadFile(TDirectoryFile *f)
313 for (TObject* keyobj: *f->GetListOfKeys()) {
314 TKey* key = (TKey*)keyobj;
316 TObject* obj = f->Get(key->GetName());
317 TClass* t = obj->IsA();
319 if (strcmp(t->GetName(),
"TDirectoryFile") == 0) {
320 jsroot_ReadFile((TDirectoryFile*)obj);
325static void jsroot(
const std::vector<std::string>& files)
329 assert(httpServer != NULL);
331 std::vector<TFile*> root_files;
333 printf(
"JSROOT server for %zu files:\n", files.size());
335 for (
size_t i=0; i<files.size(); i++) {
336 printf(
"file[%zu]: %s\n", i, files[i].c_str());
338 TFile* f =
new TFile(files[i].c_str(),
"READ");
341 fprintf(stderr,
"Error: cannot open ROOT file \"%s\"\n", files[i].c_str());
350 root_files.push_back(f);
354 int nreq = httpServer->ProcessRequests();
362 bool intr = gSystem->ProcessEvents();
369 printf(
"Interrupted, shutting down!\n");
373 for (TFile* f: root_files) {
393#ifdef HAVE_THTTP_SERVER
394#include "THttpServer.h"
414 fprintf(stderr,
"Waiting for all queues to empty out!\n");
416 int count_all_empty = 0;
419 int count_not_empty = 0;
420 size_t count_events = 0;
422 for (
unsigned i=0; i<mt->
fMtThreads.size(); i++) {
441 if (count_not_empty == 0) {
445 if (count_all_empty > 1) {
451 fprintf(stderr,
"Timeout waiting for all queues to empty out, %d queues still have %zu flow events!\n", count_not_empty, count_events);
462 fprintf(stderr,
"Waiting for all threads to shut down!\n");
467 int count_running = 0;
469 for (
unsigned i=0; i<mt->
fMtThreads.size(); i++) {
474 if (count_running == 0) {
479 fprintf(stderr,
"Timeout waiting for all threads to shut down, %d still running!\n", count_running);
487 fprintf(stderr,
"Joining all threads!\n");
488 for (
unsigned i=0; i<mt->
fMtThreads.size(); i++) {
497 fprintf(stderr,
"Thread %d failed to shut down!\n", i);
504 fMtFlowQueueMutex(nModules),
505 fMtFlowQueue(nModules),
506 fMtFlagQueue(nModules),
507 fMtThreads(nModules,NULL),
508 fMtThreadIsRunning(nModules),
509 fMtThreadIsBusy(nModules),
510 fMtShutdownRequested(false),
511 fMtQuitRequested(false)
536 for (
size_t i=0; i<nmodules; i++) {
554 printf(
"TAMultithreadInfo::dtor: deleted %d queued flow events!\n", count);
578 if (
full && (i==0)) {
603 if (!mt)
return false;
623 printf(
"Multithread queue lengths:\n");
641 gModules =
new std::vector<TAFactory*>;
649 gettimeofday(&tv,NULL);
650 return tv.tv_sec + 0.000001*tv.tv_usec;
673 return elapsed_seconds.count();
732 Profiler(
const int queue_interval_check );
734 void Begin(
TARunInfo* runinfo,
const std::vector<TARunObject*> fRunRun );
741 void AddModuleMap(
const char* UserProfileName,
unsigned long hash);
750 fQueueIntervalCounter(0),
751 fQueueInterval(queue_interval_check)
755 printf(
"Profiler::ctor\n");
759 fStartUser = std::chrono::system_clock::now();
763 fprintf(stderr,
"Error: manalyzer must be built with ROOT for using the user profiling tools\n");
770 printf(
"Profiler::dtor\n");
788 printf(
"Profiler::begin\n");
807 Double_t bins[Nbins+1];
809 Double_t TimeRange = 10;
812 for (
int i=0; i<Nbins+1; i++) {
813 bins[i] = TimeRange*pow(1.1,i)/pow(1.1,Nbins);
821 for (
size_t i = 0; i < runrun.size(); i++) {
823 if (runrun[i]->fModuleName.empty())
824 fModuleNames.push_back(
"Unnamed Module " + std::to_string(i));
845 TH1D* Histo =
new TH1D( TString(std::to_string(i) +
"_" +
fModuleNames.at(i)),
846 TString(
fModuleNames.at(i) +
" Event Proccessing Time; s"),
851 TH1D* AnalyzeEventHisto =
new TH1D(TString(std::to_string(i) +
"_" +
fModuleNames.at(i) +
"_TMEvent"),
852 TString(
fModuleNames.at(i) +
" Flow Proccessing Time; s"),
865 TH1D* QueueHisto =
new TH1D(TString(std::to_string(i) +
"_" +
fModuleNames.at(i) +
"_Queue"),
866 TString(
fModuleNames.at(i) +
" Multithread Queue Length; Queue Depth"),
882 printf(
"Profiler::log\n");
891 std::chrono::duration<double> elapsed_seconds = stop - start;
892 double dt = elapsed_seconds.count();
910 printf(
"Profiler::log_AnalyzeEvent_time\n");
919 std::chrono::duration<double> elapsed_seconds = stop - start;
920 double dt = elapsed_seconds.count();
939 printf(
"Profiler::log_mt_queue_length\n");
960 printf(
"Profiler::LogUserWindows\n");
964 std::vector<TAFlowEvent*> flowArray;
968 flowArray.push_back(f);
972 for (
int ii=FlowEvents-1; ii>=0; ii--) {
977 unsigned int hash = std::hash<std::string>{}(timer->
fModuleName);
995 printf(
"Profiler::AddModuleMap\n");
1003 Double_t bins[Nbins+1];
1004 Double_t TimeRange = 10;
1005 for (
int i=0; i<Nbins+1; i++) {
1006 bins[i] = TimeRange*pow(1.1,i)/pow(1.1,Nbins);
1008 TH1D* Histo =
new TH1D(UserProfileName,UserProfileName,Nbins,bins);
1019 printf(
"Profiler::End\n");
1061 double AllAnalyzeFlowEventTime=0;
1063 AllAnalyzeFlowEventTime += n;
1064 double AllAnalyzeEventTime=0;
1066 AllAnalyzeEventTime += n;
1068 printf(
"Module average processing time\n");
1069 printf(
" \t\t\t\tAnalyzeEvent (one thread) \tAnalyzeFlowEvent (multithreadable)\n");
1070 printf(
"Module\t\t\t\tEntries\tMean(ms)RMS(ms)\tMax(ms)\tSum(s)\tEntries\tMean(ms)RMS(ms)\tMax(ms)\tSum(s)\n");
1071 printf(
"----------------------------------------------------------------------------------------------------------------\n");
1075 printf(
"\t%d\t%.1f\t%.1f\t%.1f\t%.3f",
1082 printf(
"\t-\t-\t-\t-\t-");
1085 printf(
"\t%d\t%.1f\t%.1f\t%.1f\t%.3f",
1092 printf(
"\t-\t-\t-\t-\t-");
1095 printf(
"----------------------------------------------------------------------------------------------------------------\n");
1096 printf(
" Analyse TMEvent total time %f\n",AllAnalyzeEventTime);
1097 printf(
" Analyse FlowEvent total time %f\n",AllAnalyzeFlowEventTime);
1100 printf(
"Custom profiling windows\tEntries\tMean(ms)RMS(ms)\tMax(ms)\tSum(s)\n");
1101 printf(
"----------------------------------------------------------------------\n");
1103 printf(
"%-25s\t%d\t%.1f\t%.1f\t%.1f\t%.3f\t\n",
fUserHistograms.at(i)->GetTitle(),
1110 printf(
"----------------------------------------------------------------------\n");
1112 printf(
"----------------------------------------------------------------------------------------------------------------\n");
1115 fprintf(stderr,
"To use custom profile windows, please build rootana with ROOT\n");
1120 double cputime = (double)(clock() -
fStartCPU)/CLOCKS_PER_SEC;
1121 std::chrono::duration<double> usertime = std::chrono::system_clock::now() -
fStartUser;
1122 printf(
"%s\tCPU time: %.2fs\tUser time: %.2fs\tAverage CPU Usage: ~%.1f%%\n",
1126 100.*cputime/usertime.count());
1148 bool fMultithreadEnabled =
false;
1150 bool fProfilerEnabled =
false;
1153 RunHandler(
const std::vector<std::string>& args,
bool multithread,
bool profile,
int queue_interval_check)
1157 fMultithreadEnabled = multithread;
1159 fProfilerEnabled = profile;
1160 fProfilerIntervalCheck = queue_interval_check;
1178 size_t nModules = fRunRun.size();
1222 flow = fRunRun[i]->AnalyzeFlowEvent(fRunInfo, flag, flow);
1245 if (i==nModules-1) {
1270 assert(fRunInfo == NULL);
1271 assert(fRunRun.size() == 0);
1273 fRunInfo =
new TARunInfo(run_number, file_name, fArgs);
1275 if (fProfilerEnabled)
1276 fProfiler =
new Profiler( fProfilerIntervalCheck );
1278 size_t nModules = (*gModules).size();
1280 for (
size_t i=0; i<nModules; i++)
1281 fRunRun.push_back((*
gModules)[i]->NewRunObject(fRunInfo));
1283 std::stable_sort(fRunRun.begin(), fRunRun.end(),
compare_order);
1286 printf(
"Created %zu module run objects:\n", fRunRun.size());
1287 for (
size_t i=0; i<fRunRun.size(); i++) {
1288 if (!fRunRun[i]->fModuleName.empty()) {
1289 printf(
"module %2zu: \"%s\" order %d\n", i, fRunRun[i]->fModuleName.c_str(), fRunRun[i]->fModuleOrder);
1291 printf(
"module %2zu: %p order %d\n", i, fRunRun[i], fRunRun[i]->fModuleOrder);
1297 if (fRunInfo->
fRoot)
1301 if (fMultithreadEnabled) {
1304 for (
size_t i=0; i<nModules; i++) {
1306 printf(
"Create fMtFlowQueue thread %zu\n", i);
1315 assert(fRunInfo != NULL);
1316 assert(fRunInfo->
fOdb != NULL);
1319 fProfiler->
Begin(fRunInfo, fRunRun);
1321 for (
unsigned i=0; i<fRunRun.size(); i++)
1322 fRunRun[i]->BeginRun(fRunInfo);
1342 for (
unsigned i=0; i<fRunRun.size(); i++)
1343 fRunRun[i]->PreEndRun(fRunInfo);
1348 AnalyzeFlowQueue(flags);
1368 if (fRunInfo->
fOdb) {
1369 delete fRunInfo->
fOdb;
1370 fRunInfo->
fOdb = NULL;
1375 midas::odb::set_odb_source(midas::odb::STRING, std::string(fRunInfo->
fEorOdbDump.data(), fRunInfo->
fEorOdbDump.size()));
1381 for (
size_t i=0; i<fRunRun.size(); i++) {
1383 fRunRun[i]->EndRun(fRunInfo);
1387 fProfiler->
End(fRunInfo);
1396 for (
unsigned i=0; i<fRunRun.size(); i++)
1397 fRunRun[i]->NextSubrun(fRunInfo);
1404 for (
unsigned i=0; i<fRunRun.size(); i++) {
1410 assert(fRunRun.size() == 0);
1423 for (
unsigned i=0; i<fRunRun.size(); i++)
1424 fRunRun[i]->AnalyzeSpecialEvent(fRunInfo, event);
1429 for (
unsigned i=0; i<fRunRun.size(); i++) {
1431 flow = fRunRun[i]->AnalyzeFlowEvent(fRunInfo, flags, flow);
1458 flow = AnalyzeFlowEvent(&flags, flow);
1470 assert(fRunInfo != NULL);
1471 assert(fRunInfo->
fOdb != NULL);
1472 assert(event != NULL);
1473 assert(flags != NULL);
1483 for (
unsigned i=0; i<fRunRun.size(); i++) {
1485 flow = fRunRun[i]->Analyze(fRunInfo, event, flags, flow);
1502 flow = AnalyzeFlowEvent(flags, flow);
1507 if (fProfiler && !fRunInfo->
fMtInfo) {
1527 AnalyzeFlowQueue(flags);
1533 if (fFlowQueue.empty())
1537 fFlowQueue.pop_front();
1543 if (fAfterPreEndRun) {
1544 fprintf(stderr,
"Error: Calling AddToFlowQueue() after PreEndRun() is not permitted.\n");
1553 fFlowQueue.push_back(flow);
1567static bool gRunStartRequested =
false;
1568static bool gRunStopRequested =
false;
1570class RpcHandler:
public TMFeRpcHandlerInterface
1572 TMFeResult HandleBeginRun(
int run_number)
1574 printf(
"RpcHandler::HandleBeginRun(%d)\n", run_number);
1575 gRunStartRequested =
true;
1576 gRunStopRequested =
false;
1580 TMFeResult HandleEndRun(
int run_number)
1582 printf(
"RpcHandler::HandleEndRun(%d)\n", run_number);
1583 gRunStartRequested =
false;
1584 gRunStopRequested =
true;
1588 TMFeResult HandleStartAbortRun(
int run_number)
1590 printf(
"RpcHandler::HandleStartAbortRun(%d)\n", run_number);
1592 gRunStartRequested =
false;
1593 gRunStopRequested =
true;
1597 TMFeResult HandleRpc(
const char* cmd,
const char* args, std::string& result)
1603TMFeResult ReceiveEvent(TMEventBuffer* b,
TMEvent *e,
int timeout_msec = 0)
1610 TMFeResult r = b->ReceiveEvent(&e->
data, timeout_msec);
1615 if (e->
data.size() == 0)
1625static int ProcessMidasOnlineTmfe(
const std::vector<std::string>& args,
const char* progname,
const char* hostname,
const char* exptname,
const char* bufname,
int event_id,
int trigger_mask,
const char* sampling_type_string,
int num_analyze,
TMWriterInterface* writer,
bool multithread,
bool profiler,
int queue_interval_check)
1627 TMFE *mfe = TMFE::Instance();
1629 TMFeResult r = mfe->Connect(progname, hostname, exptname);
1632 fprintf(stderr,
"Cannot connect to MIDAS: %s\n", r.error_message.c_str());
1638 TMEventBuffer *b =
new TMEventBuffer(mfe);
1642 r = b->OpenBuffer(bufname);
1645 fprintf(stderr,
"Cannot open event buffer \"%s\": %s\n", bufname, r.error_message.c_str());
1650 size_t cache_size = 100000;
1651 if(!strcmp(sampling_type_string,
"GET_RECENT"))
1653 r = b->SetCacheSize(cache_size, 0);
1656 fprintf(stderr,
"Cannot set cache size on event buffer \"%s\": %s\n", bufname, r.error_message.c_str());
1662 r = b->AddRequest(event_id, trigger_mask, sampling_type_string);
1665 fprintf(stderr,
"Cannot add event request on event buffer \"%s\": %s\n", bufname, r.error_message.c_str());
1669 RpcHandler* h =
new RpcHandler();
1671 mfe->AddRpcHandler(h);
1673 mfe->DeregisterTransitionPause();
1674 mfe->DeregisterTransitionResume();
1675 mfe->SetTransitionSequenceStart(300);
1676 mfe->SetTransitionSequenceStop(700);
1678 mfe->StartRpcThread();
1682 RunHandler rh(args, multithread, profiler, queue_interval_check);
1684 for (
unsigned i=0; i<(*gModules).size(); i++)
1687 if (mfe->fStateRunning) {
1688 rh.CreateRun(mfe->fRunNumber, NULL);
1689 rh.fRunInfo->fOdb = mfe->fOdbRoot;
1694 TFile* no_run_file = NULL;
1699 while (!mfe->fShutdownRequested) {
1700 bool do_sleep =
true;
1702 if (gRunStartRequested) {
1703 gRunStartRequested =
false;
1708 rh.fRunInfo->fOdb = NULL;
1715 printf(
"JSROOT close file\n");
1718 no_run_file->Close();
1724 rh.CreateRun(mfe->fRunNumber, NULL);
1725 rh.fRunInfo->fOdb = mfe->fOdbRoot;
1731 if (gRunStopRequested) {
1732 gRunStopRequested =
false;
1737 rh.fRunInfo->fOdb = NULL;
1748 r = ReceiveEvent(b, &e, 100);
1751 fprintf(stderr,
"Cannot read event on event buffer \"%s\": %s\n", bufname, r.error_message.c_str());
1758 if ((e.
data_size > 0) && (rh.fRunInfo != NULL)) {
1765 rh.AnalyzeEvent(&e, &flags, writer);
1768 mfe->fShutdownRequested =
true;
1771 if (num_analyze > 0) {
1773 if (num_analyze == 0) {
1774 mfe->fShutdownRequested =
true;
1789 printf(
"JSROOT open file \"%s\"\n", filename.c_str());
1792 no_run_file =
new TFile(filename.c_str(),
"READ");
1794 if (!no_run_file->IsOpen()) {
1795 fprintf(stderr,
"Error: cannot open ROOT file \"%s\"\n", filename.c_str());
1797 jsroot_ReadFile(no_run_file);
1804#ifdef HAVE_THTTP_SERVER
1815 gSystem->DispatchOneEvent(kTRUE);
1819 if (rh.fRunInfo && rh.fRunInfo->fMtInfo) {
1824 gSystem->DispatchOneEvent(kTRUE);
1842 rh.fRunInfo->fOdb = NULL;
1849 printf(
"JSROOT close file\n");
1852 no_run_file->Close();
1858 for (
unsigned i=0; i<(*gModules).size(); i++)
1862 r = b->CloseBuffer();
1868 fprintf(stderr,
"Cannot close event buffer \"%s\": %s\n", bufname, r.error_message.c_str());
1890 int fNumAnalyze = 0;
1896 : fRun(args, multithread, profiler, queue_interval_check)
1898 fNumAnalyze = num_analyze;
1916 void Transition(
int transition,
int run_number,
int transition_time)
1920 if (transition == TR_START) {
1931 StartRun(run_number);
1932 printf(
"Begin run: %d\n", run_number);
1933 }
else if (transition == TR_STOP) {
1940 printf(
"End of run %d\n", run_number);
1944 void Event(
const void* data,
int data_size)
1961 if (fNumAnalyze > 0) {
1963 if (fNumAnalyze == 0)
1974static int ProcessMidasOnlineOld(
const std::vector<std::string>& args,
const char* hostname,
const char* exptname,
int num_analyze,
TMWriterInterface* writer,
bool multithread,
bool profiler,
int queue_interval_check)
1978 int err = midas->
connect(hostname, exptname,
"rootana");
1980 fprintf(stderr,
"Cannot connect to MIDAS, error %d\n", err);
1998 odb->
RI(
"runinfo/run number", &run_number);
1999 odb->
RI(
"runinfo/state", &run_state);
2001 for (
unsigned i=0; i<(*gModules).size(); i++)
2004 if ((run_state == STATE_RUNNING)||(run_state == STATE_PAUSED)) {
2009#ifdef HAVE_THTTP_SERVER
2016 gSystem->DispatchOneEvent(kTRUE);
2030 for (
unsigned i=0; i<(*gModules).size(); i++)
2034 delete odb; odb = NULL;
2048static int ProcessMidasFiles(
const std::vector<std::string>& files,
const std::vector<std::string>& args,
int num_skip,
int num_analyze,
TMWriterInterface* writer,
bool multithread,
bool profiler,
int queue_interval_check)
2050 int number_of_missing_files = 0;
2054 for (
unsigned i=0; i<files.size(); i++)
2057 for (
unsigned i=0; i<(*gModules).size(); i++)
2060 RunHandler run(args, multithread, profiler, queue_interval_check);
2073 printf(
"Could not open \"%s\", error: %s\n", filename.c_str(), reader->
fErrorString.c_str());
2075 number_of_missing_files++;
2090 if (event->event_id == 0x8000)
2092 int runno =
event->serial_number;
2113 run.
fRunInfo->
fBorOdbDump.assign(event->GetEventData(), event->GetEventData() + event->data_size);
2128 else if (event->event_id == 0x8001)
2130 run.
fRunInfo->
fEorOdbDump.assign(event->GetEventData(), event->GetEventData() + event->data_size);
2138 else if (event->event_id == 0x8002)
2163 if (num_analyze > 0) {
2165 if (num_analyze == 0)
2178 gSystem->DispatchOneEvent(kTRUE);
2187 gSystem->DispatchOneEvent(kTRUE);
2201#ifdef HAVE_THTTP_SERVER
2204 gSystem->DispatchOneEvent(kTRUE);
2218 for (
unsigned i=0; i<(*gModules).size(); i++)
2221 if (number_of_missing_files) {
2222 printf(
"%d midas files were not openable\n", number_of_missing_files);
2223 return number_of_missing_files;
2229static int ProcessDemoMode(
const std::vector<std::string>& args,
int num_skip,
int num_analyze,
TMWriterInterface* writer,
bool multithread,
bool profiler,
int queue_interval_check)
2231 for (
unsigned i=0; i<(*gModules).size(); i++)
2234 RunHandler run(args, multithread, profiler, queue_interval_check);
2240 for (
unsigned i=0;
true; i++) {
2242 snprintf(s,
sizeof(s),
"%03d", i);
2243 std::string filename = std::string(
"demo_subrun_") + s;
2262 for (
unsigned j=0; j<100; j++) {
2263 event->Init(0x0001, 0xFFFF, j+1, 0, 0);
2265 uint32_t test_data[] = { 0x11112222, 0x33334444, 0x55556666, 0x77778888 };
2266 event->AddBank(
"TEST",
TID_DWORD, (
const char*)test_data,
sizeof(test_data));
2269 slow_data[0] = (drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() + drand48() - 6.0)*10.0;
2270 event->AddBank(
"SLOW",
TID_FLOAT, (
const char*)slow_data,
sizeof(slow_data));
2282 if (num_analyze > 0) {
2284 if (num_analyze == 0)
2292#ifdef HAVE_THTTP_SERVER
2299 gSystem->DispatchOneEvent(kTRUE);
2319 for (
unsigned i=0; i<(*gModules).size(); i++)
2328static int ShowMem(
const char* label)
2333 FILE* fp = fopen(
"/proc/self/statm",
"r");
2338 fscanf(fp,
"%d",&mem);
2342 printf(
"memory at %s is %d\n", label, mem);
2355 printf(
"EventDumpModule::ctor, run %d\n", runinfo->
fRunNo);
2357 fModuleName =
"EventDump";
2364 printf(
"EventDumpModule::dtor!\n");
2369 printf(
"EventDumpModule::BeginRun, run %d\n", runinfo->
fRunNo);
2374 printf(
"EventDumpModule::EndRun, run %d\n", runinfo->
fRunNo);
2379 printf(
"EventDumpModule::NextSubrun, run %d, file %s\n", runinfo->
fRunNo, runinfo->
fFileName.c_str());
2384 printf(
"EventDumpModule::PauseRun, run %d\n", runinfo->
fRunNo);
2389 printf(
"EventDumpModule::ResumeRun, run %d\n", runinfo->
fRunNo);
2394 printf(
"EventDumpModule::Analyze, run %d, ", runinfo->
fRunNo);
2395 event->FindAllBanks();
2396 std::string h =
event->HeaderToString();
2397 std::string b =
event->BankListToString();
2398 printf(
"%s: %s\n", h.c_str(), b.c_str());
2404 printf(
"EventDumpModule::AnalyzeSpecialEvent, run %d, event serno %d, id 0x%04x, data size %d\n", runinfo->
fRunNo, event->
serial_number, (
int)event->
event_id, event->
data_size);
2412 void Init(
const std::vector<std::string> &args)
2415 printf(
"EventDumpModuleFactory::Init!\n");
2421 printf(
"EventDumpModuleFactory::Finish!\n");
2427 printf(
"EventDumpModuleFactory::NewRunObject, run %d, file %s\n", runinfo->
fRunNo, runinfo->
fFileName.c_str());
2434#include <TGButton.h>
2435#include <TBrowser.h>
2439#define CTRL_CONTINUE 3
2441#define CTRL_NEXT_FLOW 5
2443#define CTRL_TBROWSER 11
2472 printf(
"Pressed!\n");
2477 printf(
"Released!\n");
2485 fHolder->
fValue = fValue;
2513 printf(
"MainWindow::ctor!\n");
2518 SetWindowName(
"ROOT Analyzer Control");
2521 fMenu =
new TGPopupMenu(gClient->GetRoot());
2523 fMenu->AddEntry(
"-", 0);
2528 fMenu->AddEntry(
"-", 0);
2531 fMenuBarItemLayout =
new TGLayoutHints(kLHintsTop|kLHintsLeft, 0, 4, 0, 0);
2533 fMenu->Associate(
this);
2535 fMenuBar =
new TGMenuBar(
this, 1, 1, kRaisedFrame);
2536 fMenuBar->AddPopup(
"&Rootana", fMenu, fMenuBarItemLayout);
2539 AddFrame(fMenuBar,
new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsExpandX));
2541 fButtonsFrame =
new TGVerticalFrame(
this);
2546 fButtonsFrame->AddFrame(fNextButton,
new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
2547 fButtonsFrame->AddFrame(fNextFlowButton,
new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
2549 TGHorizontalFrame *hframe =
new TGHorizontalFrame(fButtonsFrame);
2554 hframe->AddFrame(fContinueButton,
new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
2555 hframe->AddFrame(fPauseButton,
new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
2557 fButtonsFrame->AddFrame(hframe,
new TGLayoutHints(kLHintsExpandX));
2560 fButtonsFrame->AddFrame(fQuitButton,
new TGLayoutHints(kLHintsExpandX, 1, 1, 1, 1));
2562 AddFrame(fButtonsFrame,
new TGLayoutHints(kLHintsExpandX));
2566 Resize(GetDefaultSize());
2573 printf(
"MainWindow::dtor!\n");
2577 delete fMenuBarItemLayout;
2583 printf(
"MainWindow::CloseWindow()\n");
2593 switch (GET_MSG(msg))
2598 switch (GET_SUBMSG(msg))
2641 printf(
"InteractiveModule::ctor, run %d\n", runinfo->
fRunNo);
2642 fModuleName =
"InteractiveModule";
2643 fModuleOrder = 9999;
2650 if (!fgCtrlWindow && runinfo->
fRoot->
fgApp) {
2651 fgCtrlWindow =
new MainWindow(gClient->GetRoot(), 200, 300, fgHolder);
2659 printf(
"InteractiveModule::dtor!\n");
2664 printf(
"InteractiveModule::BeginRun, run %d\n", runinfo->
fRunNo);
2669 printf(
"InteractiveModule::EndRun, run %d\n", runinfo->
fRunNo);
2678#ifdef HAVE_THTTP_SERVER
2685 gSystem->DispatchOneEvent(kTRUE);
2690 TMFE* mfe = TMFE::Instance();
2692 if (mfe->fShutdownRequested) {
2705 int ctrl = fgHolder->
fValue;
2723 printf(
"InteractiveModule::PauseRun, run %d\n", runinfo->
fRunNo);
2728 printf(
"InteractiveModule::ResumeRun, run %d\n", runinfo->
fRunNo);
2736#ifdef HAVE_THTTP_SERVER
2743 gSystem->DispatchOneEvent(kTRUE);
2748 TMFE* mfe = TMFE::Instance();
2750 if (mfe->fShutdownRequested) {
2764 int ctrl = fgHolder->
fValue;
2786 fprintf(stdout,
"manalyzer> "); fflush(stdout);
2787 char* s = fgets(str,
sizeof(str)-1, stdin);
2795 printf(
"command [%s]\n", str);
2797 if (str[0] ==
'h') {
2798 printf(
"Interactive manalyzer commands:\n");
2799 printf(
" q - quit\n");
2800 printf(
" h - help\n");
2801 printf(
" c - continue until next TAFlag_DISPLAY event\n");
2802 printf(
" n - next event\n");
2803 printf(
" aNNN - analyze N events, i.e. \"a10\"\n");
2804 }
else if (str[0] ==
'q') {
2807 }
else if (str[0] ==
'n') {
2809 }
else if (str[0] ==
'c') {
2812 }
else if (str[0] ==
'a') {
2813 int num = atoi(str+1);
2814 printf(
"Analyzing %d events\n", num);
2825 printf(
"InteractiveModule::Analyze, run %d, %s\n", runinfo->
fRunNo, event->
HeaderToString().c_str());
2847 InteractiveLoop(runinfo, flags);
2854 printf(
"InteractiveModule::AnalyzeFlowEvent, run %d\n", runinfo->
fRunNo);
2871 InteractiveLoop(runinfo, flags);
2879 printf(
"InteractiveModule::AnalyzeSpecialEvent, run %d, event serno %d, id 0x%04x, data size %d\n", runinfo->
fRunNo, event->
serial_number, (
int)event->
event_id, event->
data_size);
2892 void Init(
const std::vector<std::string> &args)
2895 printf(
"InteractiveModuleFactory::Init!\n");
2901 printf(
"InteractiveModuleFactory::Finish!\n");
2907 printf(
"InteractiveModuleFactory::NewRunObject, run %d, file %s\n", runinfo->
fRunNo, runinfo->
fFileName.c_str());
2920 printf(
"\nUsage: ./manalyzer.exe [-h] [-R8081] [-oOutputfile.mid] [file1 file2 ...] [-- arguments passed to modules ...]\n");
2922 printf(
"-h: print this help message\n");
2923 printf(
"--demo: activate the demo mode, online connection or input file not needed, midas events are generated internally, add -e0 or -eNNN to set number of demo events \n");
2925 printf(
"-Hhostname: connect to MIDAS experiment on given host\n");
2926 printf(
"-Eexptname: connect to this MIDAS experiment\n");
2927 printf(
"--midas-progname SSS -- set analyzer's MIDAS program name, default is \"ana\"\n");
2928 printf(
"--midas-hostname HOSTNAME[:PORT] -- connect to MIDAS mserver on given host and port\n");
2929 printf(
"--midas-exptname EXPTNAME -- connect to given experiment\n");
2930 printf(
"--midas-buffer BUFZZZ -- connect to given MIDAS event buffer\n");
2931 printf(
"--midas-sampling SSS -- sample events from MIDAS event buffer: GET_ALL=get every event (will block the event writers, GET_NONBLOCKING=get as many as we can process, GET_RECENT=get recent events, see bm_receive_event(). Default is GET_NONBLOCKING\n");
2932 printf(
"--midas-event-id III -- receive only events with matching event ID\n");
2933 printf(
"--midas-trigger-mask 0xMASK -- receive only events with matching trigger mask\n");
2935 printf(
"-oOutputfile.mid: write selected events into this file\n");
2936 printf(
"-Rnnnn: Start the ROOT THttpServer HTTP server on specified tcp port, use -R8081, access by firefox http://localhost:8081\n");
2937 printf(
"-eNNN: Number of events to analyze, 0=unlimited\n");
2938 printf(
"-sNNN: Number of events to skip before starting analysis\n");
2940 printf(
"--dump: activate the event dump module\n");
2942 printf(
"-t: Enable tracing of constructors, destructors and function calls\n");
2943 printf(
"-m: Enable memory leak debugging\n");
2944 printf(
"-g: Enable graphics display when processing data files\n");
2945 printf(
"-i: Enable intractive mode\n");
2947 printf(
"--mt: Enable multithreaded mode. Extra multithread config settings:\n");
2952 printf(
"--no-profiler: Turn off manalyzer module profiler\n");
2953 printf(
"--pqiNNN: Profile multithread queue lengths every NNN events \n");
2956 printf(
"-Doutputdirectory: Specify output root file directory\n");
2957 printf(
"-Ooutputfile.root: Specify output root file filename\n");
2958 printf(
"--jsroot: After analysis is finished, keep jsroot running\n");
2961 printf(
"--: All following arguments are passed to the analyzer modules Init() method\n");
2963 printf(
"Analyzer modules usage:\n");
2965 for (
unsigned i=0; i<(*gModules).size(); i++) {
2966 (*gModules)[i]->Usage();
2970 printf(
"Example1: analyze online data: ./manalyzer.exe -R9091\n");
2971 printf(
"Example2: analyze existing data: ./manalyzer.exe /data/alpha/current/run00500.mid\n");
2979 return (s.substr(0, strlen(prefix)) == prefix);
2986 setbuf(stdout, NULL);
2987 setbuf(stderr, NULL);
2989 signal(SIGILL, SIG_DFL);
2990 signal(SIGBUS, SIG_DFL);
2991 signal(SIGSEGV, SIG_DFL);
2992 signal(SIGPIPE, SIG_DFL);
2994 std::vector<std::string> args;
2995 for (
int i=0; i<argc; i++) {
2996 if (strcmp(argv[i],
"-h")==0)
2998 args.push_back(argv[i]);
3003 int num_analyze = 0;
3007 bool event_dump =
false;
3008 bool demo_mode =
false;
3010 bool root_graphics =
false;
3012 bool interactive =
false;
3014 bool multithread =
false;
3017 bool enable_jsroot =
false;
3021 bool performance_profiler =
true;
3023 bool performance_profiler =
false;
3025 int snap_shot_queue_length = 100;
3027 std::vector<std::string> files;
3028 std::vector<std::string> modargs;
3031 std::string midas_hostname =
"";
3032 std::string midas_exptname =
"";
3033 std::string midas_progname =
"ana";
3034 std::string midas_buffer =
"SYSTEM";
3036 std::string midas_sampling =
"GET_NONBLOCKING";
3037 int midas_event_id = -1;
3038 int midas_trigger_mask = -1;
3041 for (
unsigned int i=1; i<args.size(); i++) {
3042 std::string arg = args[i];
3046 for (
unsigned j=i+1; j<args.size(); j++)
3047 modargs.push_back(args[j]);
3049 }
else if (arg ==
"--dump") {
3051 }
else if (arg ==
"--demo") {
3055 }
else if (arg ==
"-g") {
3056 root_graphics =
true;
3058 }
else if (arg ==
"-i") {
3060 }
else if (arg ==
"-t") {
3067 num_skip = atoi(arg.c_str()+2);
3069 num_analyze = atoi(arg.c_str()+2);
3073 httpPort = atoi(arg.c_str()+2);
3076 midas_hostname = arg.c_str()+2;
3078 midas_exptname = arg.c_str()+2;
3079 }
else if (arg ==
"--midas-progname") {
3080 midas_progname = args[i+1]; i++;
3081 }
else if (arg ==
"--midas-hostname") {
3082 midas_hostname = args[i+1]; i++;
3083 }
else if (arg ==
"--midas-exptname") {
3084 midas_exptname = args[i+1]; i++;
3085 }
else if (arg ==
"--midas-buffer") {
3086 midas_buffer = args[i+1]; i++;
3087 }
else if (arg ==
"--midas-sampling") {
3088 midas_sampling = args[i+1]; i++;
3089 }
else if (arg ==
"--midas-event-id") {
3090 midas_event_id = atoi(args[i+1].c_str()); i++;
3091 }
else if (arg ==
"--midas-trigger-mask") {
3092 midas_trigger_mask = strtoul(args[i+1].c_str(), NULL, 0); i++;
3100 }
else if (arg ==
"--mt") {
3102 }
else if (arg ==
"--no-profiler") {
3103 performance_profiler = 0;
3105 snap_shot_queue_length = atoi(arg.c_str()+5);
3111 }
else if (arg ==
"--jsroot") {
3112 enable_jsroot =
true;
3114 }
else if (arg ==
"-h") {
3116 }
else if (arg[0] ==
'-') {
3119 files.push_back(args[i]);
3124 gModules =
new std::vector<TAFactory*>;
3126 if ((*gModules).size() == 0)
3136 printf(
"Registered modules: %zu\n", (*gModules).size());
3142 ROOT::EnableImplicitMT();
3143 ROOT::EnableThreadSafety();
3146 if (root_graphics) {
3155#ifdef HAVE_THTTP_SERVER
3157 snprintf(str,
sizeof(str),
"http:127.0.0.1:%d?cors", httpPort);
3158 THttpServer *s =
new THttpServer(str);
3159 if (!s->IsAnyEngine()) {
3160 fprintf(stderr,
"ERROR: Cannot start web server on http port %d, see previous error message.\n", httpPort);
3166 fprintf(stderr,
"ERROR: No support for the THttpServer!\n");
3170 for (
unsigned i=0; i<files.size(); i++) {
3171 printf(
"file[%d]: %s\n", i, files[i].c_str());
3177 exit_state =
ProcessDemoMode(modargs, num_skip, num_analyze, writer, multithread, performance_profiler, snap_shot_queue_length);
3178 }
else if (files.size() > 0) {
3179 exit_state =
ProcessMidasFiles(files, modargs, num_skip, num_analyze, writer, multithread, performance_profiler, snap_shot_queue_length);
3183 exit_state = ProcessMidasOnlineTmfe(modargs, midas_progname.c_str(), midas_hostname.c_str(), midas_exptname.c_str(), midas_buffer.c_str(), midas_event_id, midas_trigger_mask, midas_sampling.c_str(), num_analyze, writer, multithread, performance_profiler, snap_shot_queue_length);
3185 exit_state =
ProcessMidasOnlineOld(modargs, midas_hostname.c_str(), midas_exptname.c_str(), num_analyze, writer, multithread, performance_profiler, snap_shot_queue_length);
3189 enable_jsroot =
false;
3200#ifdef HAVE_THTTP_SERVER
3202 printf(
"Starting jsroot. Use Ctrl-C to stop.\n");
R__EXTERN TDirectory * gDirectory
TARunObject * NewRunObject(TARunInfo *runinfo)
void Init(const std::vector< std::string > &args)
void PauseRun(TARunInfo *runinfo)
EventDumpModule(TARunInfo *runinfo)
TAFlowEvent * Analyze(TARunInfo *runinfo, TMEvent *event, TAFlags *flags, TAFlowEvent *flow)
void EndRun(TARunInfo *runinfo)
void NextSubrun(TARunInfo *runinfo)
void AnalyzeSpecialEvent(TARunInfo *runinfo, TMEvent *event)
void BeginRun(TARunInfo *runinfo)
void ResumeRun(TARunInfo *runinfo)
void Init(const std::vector< std::string > &args)
TARunObject * NewRunObject(TARunInfo *runinfo)
TAFlowEvent * AnalyzeFlowEvent(TARunInfo *runinfo, TAFlags *flags, TAFlowEvent *flow)
void PauseRun(TARunInfo *runinfo)
void EndRun(TARunInfo *runinfo)
static MainWindow * fgCtrlWindow
void ResumeRun(TARunInfo *runinfo)
TAFlowEvent * Analyze(TARunInfo *runinfo, TMEvent *event, TAFlags *flags, TAFlowEvent *flow)
InteractiveModule(TARunInfo *runinfo)
static ValueHolder * fgHolder
void InteractiveLoop(TARunInfo *runinfo, TAFlags *flags)
void AnalyzeSpecialEvent(TARunInfo *runinfo, TMEvent *event)
void BeginRun(TARunInfo *runinfo)
virtual void RU32(const char *varname, uint32_t *value, bool create=false, MVOdbError *error=NULL)=0
virtual void RI(const char *varname, int *value, bool create=false, MVOdbError *error=NULL)=0
TGLayoutHints * fMenuBarItemLayout
TextButton * fNextFlowButton
MainWindow(const TGWindow *w, int s1, int s2, ValueHolder *holder)
TGCompositeFrame * fButtonsFrame
TextButton * fPauseButton
TextButton * fContinueButton
Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
void Event(const void *data, int data_size)
void Transition(int transition, int run_number, int transition_time)
OnlineHandler(int num_analyze, TMWriterInterface *writer, MVOdb *odb, const std::vector< std::string > &args, bool multithread, bool profiler, int queue_interval_check)
void StartRun(int run_number)
std::vector< double > fAnalyzeFlowEventRMS
void LogAnalyzeEvent(TAFlags *flag, TAFlowEvent *flow, const int i, const TAClock &start)
void LogUserWindows(TAFlags *flag, TAFlowEvent *flow)
std::vector< double > fAnalyzeFlowEventTimeTotal
std::vector< double > fTotalUserTime
std::vector< int > fAnalyzeEventEntries
std::vector< TH1D * > fUserHistograms
std::vector< double > fAnalyzeFlowEventMean
std::atomic< int > fQueueIntervalCounter
std::vector< double > fAnalyzeEventRMS
std::vector< double > fAnalyzeEventTimeMax
void LogAnalyzeFlowEvent(TAFlags *flag, TAFlowEvent *flow, const int i, const TAClock &start)
std::vector< std::string > fModuleNames
void End(TARunInfo *runinfo)
std::vector< TH1D * > fAnalyzeFlowEventTimeHistograms
std::chrono::system_clock::time_point fStartUser
void Begin(TARunInfo *runinfo, const std::vector< TARunObject * > fRunRun)
std::vector< double > fAnalyzeEventTimeTotal
void AddModuleMap(const char *UserProfileName, unsigned long hash)
std::vector< double > fAnalyzeFlowEventTimeMax
void LogMTQueueLength(TARunInfo *runinfo)
std::map< unsigned int, int > fUserMap
std::vector< double > fAnalyzeEventMean
std::vector< double > fMaxUserTime
std::vector< TH1D * > fAnalyzeEventTimeHistograms
Profiler(const int queue_interval_check)
std::vector< int > fAnalyzeFlowEventEntries
std::vector< TH1D * > fAnalysisQueue
std::vector< TARunObject * > fRunRun
std::vector< std::string > fArgs
void AnalyzeEvent(TMEvent *event, TAFlags *flags, TMWriterInterface *writer)
void CreateRun(int run_number, const char *file_name)
void AnalyzeSpecialEvent(TMEvent *event)
void EndRun(TAFlags *flags)
TAFlowEvent * AnalyzeFlowEvent(TAFlags *flags, TAFlowEvent *flow)
void PerModuleThread(size_t i)
int fProfilerIntervalCheck
RunHandler(const std::vector< std::string > &args, bool multithread, bool profile, int queue_interval_check)
void AnalyzeFlowQueue(TAFlags *ana_flags)
virtual void Init(const std::vector< std::string > &args)
int fMtQueueFullUSleepTime
std::vector< TAFlagsQueue > fMtFlagQueue
std::vector< std::mutex > fMtFlowQueueMutex
int fMtQueueEmptyUSleepTime
std::atomic< bool > fMtShutdownRequested
std::vector< std::thread * > fMtThreads
std::vector< std::atomic< bool > > fMtThreadIsBusy
TAMultithreadHelper(int nModules)
std::vector< TAFlowEventQueue > fMtFlowQueue
std::vector< std::atomic< bool > > fMtThreadIsRunning
std::atomic< bool > fMtQuitRequested
std::string fOutputFileName
static std::string fgUserOutputFileName
static TApplication * fgApp
static std::string fgUserOutputDirectory
static THttpServer * fgHttpServer
static std::vector< std::string > fgOutputRootFiles
static TDirectory * fgDir
void AddToFlowQueue(TAFlowEvent *)
TAFlowEvent * ReadFlowQueue()
std::vector< std::string > fArgs
std::vector< char > fBorOdbDump
static std::vector< std::string > fgFileList
std::vector< char > fEorOdbDump
TAMultithreadHelper * fMtInfo
static int fgCurrentFileIndex
virtual void EndRun(TARunInfo *runinfo)
virtual void ResumeRun(TARunInfo *runinfo)
virtual void AnalyzeSpecialEvent(TARunInfo *runinfo, TMEvent *event)
virtual void NextSubrun(TARunInfo *runinfo)
virtual TAFlowEvent * Analyze(TARunInfo *runinfo, TMEvent *event, TAFlags *flags, TAFlowEvent *flow)
virtual void PauseRun(TARunInfo *runinfo)
virtual void BeginRun(TARunInfo *runinfo)
virtual TAFlowEvent * AnalyzeFlowEvent(TARunInfo *runinfo, TAFlags *flags, TAFlowEvent *flow)
virtual void PreEndRun(TARunInfo *runinfo)
TAUserProfilerFlow(TAFlowEvent *flow, const char *name, const TAClock &start)
const std::string fModuleName
virtual TDirectory * mkdir(const char *name, const char *title="")
virtual Bool_t cd(const char *path=0)
std::string HeaderToString() const
print the MIDAS event header
void Reset()
reset everything
void ParseEvent()
parse event data
std::vector< char > data
MIDAS event bytes.
size_t event_header_size
size of MIDAS event header
uint32_t serial_number
MIDAS event serial number.
uint32_t data_size
MIDAS event data size.
uint16_t event_id
MIDAS event ID.
MIDAS online connection, including access to online ODB.
void RegisterHandler(TMHandlerInterface *h)
void registerTransitions()
Ask MIDAS to tell us about run transitions.
int disconnect()
Disconnect from MIDAS.
static TMidasOnline * instance()
int connect(const char *hostname, const char *exptname, const char *progname)
Connect to MIDAS experiment.
int eventRequest(const char *bufferName, int eventId, int triggerMask, int samplingType, bool poll=false)
Request data for delivery via callback (setEventHandler) or by polling (via receiveEvent)
TextButton(TGWindow *p, const char *text, ValueHolder *holder, int value)
std::chrono::high_resolution_clock::time_point TAClock
#define TAFlag_SKIP_PROFILE
void TMWriteEvent(TMWriterInterface *writer, const TMEvent *event)
TMWriterInterface * TMNewWriter(const char *destination)
TMEvent * TMReadEvent(TMReaderInterface *reader)
TMReaderInterface * TMNewReader(const char *source)
MVOdb * MakeMidasOdb(int hDB, MVOdbError *error=NULL)
MVOdb * MakeFileDumpOdb(const char *buf, int bufsize, MVOdbError *error=NULL)
Access ODB from a midas file dump. FOrmat could be .xml, .json or .odb.
std::chrono::high_resolution_clock::time_point TAClock
std::chrono::duration< double > TAClockDuration
#define TAFlag_SKIP_PROFILE
static int gDefaultMultithreadWaitFull
static int ProcessDemoMode(const std::vector< std::string > &args, int num_skip, int num_analyze, TMWriterInterface *writer, bool multithread, bool profiler, int queue_interval_check)
std::vector< TAFactory * > * gModules
static void MtQueueFlowEvent(TAMultithreadHelper *mt, int i, TAFlags *flag, TAFlowEvent *flow)
int manalyzer_main(int argc, char *argv[])
static int gDefaultMultithreadWaitEmpty
static bool compare_order(const TARunObject *a, const TARunObject *b)
static bool starts_with(const std::string &s, const char *prefix)
static int ProcessMidasOnlineOld(const std::vector< std::string > &args, const char *hostname, const char *exptname, int num_analyze, TMWriterInterface *writer, bool multithread, bool profiler, int queue_interval_check)
static bool gEnableShowMem
static bool MtQueueWait(TAMultithreadHelper *mt)
static void WaitForAllQueuesEmpty(TAMultithreadHelper *mt)
static int ProcessMidasFiles(const std::vector< std::string > &files, const std::vector< std::string > &args, int num_skip, int num_analyze, TMWriterInterface *writer, bool multithread, bool profiler, int queue_interval_check)
static void WaitForAllThreadsShutdown(TAMultithreadHelper *mt)
static int gDefaultMultithreadQueueLength
int ShowMem(const char *label)