From 2de1a80d997682ceca4824d1e138f9a1929219cb Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Thu, 2 Dec 2021 04:11:41 +0100 Subject: [PATCH 01/12] add silent info option -s to pcm-memory, some additional fixes --- cpucounters.cpp | 16 ++++---- pcm-memory.cpp | 99 ++++++++++++++++++++++++------------------------- utils.cpp | 14 +++++++ utils.h | 4 ++ 4 files changed, 74 insertions(+), 59 deletions(-) diff --git a/cpucounters.cpp b/cpucounters.cpp index 851d80bf..d8285c7b 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -730,27 +730,27 @@ void PCM::initRDT() auto env = std::getenv("PCM_USE_RESCTRL"); if (env != nullptr && std::string(env) == std::string("1")) { - std::cout << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because environment variable PCM_USE_RESCTRL=1\n"; + std::cerr << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because environment variable PCM_USE_RESCTRL=1\n"; resctrl.init(); useResctrl = true; return; } if (resctrl.isMounted()) { - std::cout << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because resctrl driver is mounted.\n"; + std::cerr << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because resctrl driver is mounted.\n"; resctrl.init(); useResctrl = true; return; } if (isSecureBoot()) { - std::cout << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because Secure Boot mode is enabled.\n"; + std::cerr << "INFO: using Linux resctrl driver for RDT metrics (L3OCC, LMB, RMB) because Secure Boot mode is enabled.\n"; resctrl.init(); useResctrl = true; return; } #endif - std::cout << "Initializing RMIDs" << std::endl; + std::cerr << "Initializing RMIDs" << std::endl; unsigned maxRMID; /* Calculate maximum number of RMID supported by socket */ maxRMID = getMaxRMID(); @@ -5640,16 +5640,16 @@ bool PCM::useLinuxPerfForUncore() const bool secureBoot = isSecureBoot(); #ifdef PCM_USE_PERF const auto imcIDs = enumeratePerfPMUs("imc", 100); - std::cout << "INFO: Linux perf interface to program uncore PMUs is " << (imcIDs.empty()?"NOT ":"") << "present\n"; + std::cerr << "INFO: Linux perf interface to program uncore PMUs is " << (imcIDs.empty()?"NOT ":"") << "present\n"; const char * perf_env = std::getenv("PCM_USE_UNCORE_PERF"); if (perf_env != NULL && std::string(perf_env) == std::string("1")) { - std::cout << "INFO: using Linux perf interface to program uncore PMUs because env variable PCM_USE_UNCORE_PERF=1\n"; + std::cerr << "INFO: using Linux perf interface to program uncore PMUs because env variable PCM_USE_UNCORE_PERF=1\n"; use = 1; } if (secureBoot) { - std::cout << "INFO: Secure Boot detected. Using Linux perf for uncore PMU programming.\n"; + std::cerr << "INFO: Secure Boot detected. Using Linux perf for uncore PMU programming.\n"; use = 1; } else @@ -7984,7 +7984,7 @@ void PCM::setupCustomCoreEventsForNuma(PCM::ExtendedCustomCoreEventDescription& conf.OffcoreResponseMsrValue[1] = 0x3FC0008FFF | (1 << 27) | (1 << 28) | (1 << 29); break; case PCM::ICX: - std::cout << "INFO: Monitored accesses include demand + L2 cache prefetcher, code read and RFO.\n"; + std::cerr << "INFO: Monitored accesses include demand + L2 cache prefetcher, code read and RFO.\n"; // OCR.READS_TO_CORE.LOCAL_DRAM conf.OffcoreResponseMsrValue[0] = 0x0104000477; // OCR.READS_TO_CORE.REMOTE_DRAM diff --git a/pcm-memory.cpp b/pcm-memory.cpp index 5d89f76b..cdef9283 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -101,6 +101,7 @@ void print_help(const string prog_name) cerr << " -columns=X | /columns=X => Number of columns to display the NUMA Nodes, defaults to 2.\n"; cerr << " -all | /all => Display all channels (even with no traffic)\n"; cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; + cerr << " -s => silence information output and print only measurements\n"; #ifdef _MSC_VER cerr << " --uninstallDriver | --installDriver=> (un)install driver\n"; #endif @@ -966,10 +967,13 @@ int main(int argc, char * argv[]) { set_signal_handlers(); + null_stream nullStream2; #ifdef PCM_FORCE_SILENT - null_stream nullStream1, nullStream2; + null_stream nullStream1; cout.rdbuf(&nullStream1); cerr.rdbuf(&nullStream2); +#else + check_and_set_silent(argc, argv, nullStream2); #endif cerr << "\n"; @@ -1004,12 +1008,11 @@ int main(int argc, char * argv[]) print_help(program); exit(EXIT_FAILURE); } - else - if (strncmp(*argv, "-csv",4) == 0 || - strncmp(*argv, "/csv",4) == 0) + else if (strncmp(*argv, "-csv",4) == 0 || + strncmp(*argv, "/csv",4) == 0) { csv = true; - csvheader = true; + csvheader = true; string cmd = string(*argv); size_t found = cmd.find('=',4); if (found != string::npos) { @@ -1020,14 +1023,12 @@ int main(int argc, char * argv[]) } continue; } - else - if (mainLoop.parseArg(*argv)) + else if (mainLoop.parseArg(*argv)) { continue; } - else - if (strncmp(*argv, "-columns", 8) == 0 || - strncmp(*argv, "/columns", 8) == 0) + else if (strncmp(*argv, "-columns", 8) == 0 || + strncmp(*argv, "/columns", 8) == 0) { string cmd = string(*argv); size_t found = cmd.find('=',2); @@ -1040,8 +1041,8 @@ int main(int argc, char * argv[]) } continue; } - if (strncmp(*argv, "-rank", 5) == 0 || - strncmp(*argv, "/rank", 5) == 0) + else if (strncmp(*argv, "-rank", 5) == 0 || + strncmp(*argv, "/rank", 5) == 0) { string cmd = string(*argv); size_t found = cmd.find('=',2); @@ -1049,78 +1050,75 @@ int main(int argc, char * argv[]) int rank = atoi(cmd.substr(found+1).c_str()); if (rankA >= 0 && rankB >= 0) { - cerr << "At most two DIMM ranks can be monitored \n"; - exit(EXIT_FAILURE); - } - else - { - if(rank > 7) { - cerr << "Invalid rank number " << rank << "\n"; - exit(EXIT_FAILURE); - } - if(rankA < 0) rankA = rank; - else if(rankB < 0) rankB = rank; - metrics = PartialWrites; + cerr << "At most two DIMM ranks can be monitored \n"; + exit(EXIT_FAILURE); + } else { + if(rank > 7) { + cerr << "Invalid rank number " << rank << "\n"; + exit(EXIT_FAILURE); + } + if(rankA < 0) rankA = rank; + else if(rankB < 0) rankB = rank; + metrics = PartialWrites; } } continue; } - if (strncmp(*argv, "--nochannel", 11) == 0 || - strncmp(*argv, "-nc", 3) == 0 || - strncmp(*argv, "/nc", 3) == 0) + else if (strncmp(*argv, "--nochannel", 11) == 0 || + strncmp(*argv, "-nc", 3) == 0 || + strncmp(*argv, "/nc", 3) == 0) { show_channel_output = false; continue; } - - if (strncmp(*argv, "-pmm", 4) == 0 || - strncmp(*argv, "/pmm", 4) == 0 || - strncmp(*argv, "-pmem", 5) == 0 || - strncmp(*argv, "/pmem", 5) == 0 ) + else if (strncmp(*argv, "-pmm", 4) == 0 || + strncmp(*argv, "/pmm", 4) == 0 || + strncmp(*argv, "-pmem", 5) == 0 || + strncmp(*argv, "/pmem", 5) == 0 ) { metrics = Pmem; continue; } - - if (strncmp(*argv, "-all", 4) == 0 || - strncmp(*argv, "/all", 4) == 0) + else if (strncmp(*argv, "-all", 4) == 0 || + strncmp(*argv, "/all", 4) == 0) { skipInactiveChannels = false; continue; } - - if (strncmp(*argv, "-mixed", 6) == 0 || - strncmp(*argv, "/mixed", 6) == 0) + else if (strncmp(*argv, "-mixed", 6) == 0 || + strncmp(*argv, "/mixed", 6) == 0) { metrics = PmemMixedMode; continue; } - - if (strncmp(*argv, "-mm", 3) == 0 || - strncmp(*argv, "/mm", 3) == 0) + else if (strncmp(*argv, "-mm", 3) == 0 || + strncmp(*argv, "/mm", 3) == 0) { metrics = PmemMemoryMode; show_channel_output = false; continue; } - - if (strncmp(*argv, "-partial", 8) == 0 || - strncmp(*argv, "/partial", 8) == 0) + else if (strncmp(*argv, "-partial", 8) == 0 || + strncmp(*argv, "/partial", 8) == 0) { metrics = PartialWrites; continue; } + else if (strncmp(*argv, "-s", 2) == 0 || + strncmp(*argv, "/s", 2) == 0) + { + //already checked by check_and_set_silent() + continue; + } #ifdef _MSC_VER - else - if (strncmp(*argv, "--uninstallDriver", 17) == 0) + else if (strncmp(*argv, "--uninstallDriver", 17) == 0) { Driver tmpDrvObject; tmpDrvObject.uninstall(); cerr << "msr.sys driver has been uninstalled. You might need to reboot the system to make this effective.\n"; exit(EXIT_SUCCESS); } - else - if (strncmp(*argv, "--installDriver", 15) == 0) + else if (strncmp(*argv, "--installDriver", 15) == 0) { Driver tmpDrvObject = Driver(Driver::msrLocalPath()); if (!tmpDrvObject.start()) @@ -1132,8 +1130,7 @@ int main(int argc, char * argv[]) exit(EXIT_SUCCESS); } #endif - else - if (strncmp(*argv, "--", 2) == 0) + else if (strncmp(*argv, "--", 2) == 0) { argv++; sysCmd = *argv; @@ -1156,7 +1153,7 @@ int main(int argc, char * argv[]) } continue; } - } while(argc > 1); // end of command line partsing loop + } while (argc > 1); // end of command line parsing loop m->disableJKTWorkaround(); print_cpu_details(); diff --git a/utils.cpp b/utils.cpp index c581932f..439cc285 100644 --- a/utils.cpp +++ b/utils.cpp @@ -611,4 +611,18 @@ std::string safe_getenv(const char* env) } #endif +void check_and_set_silent(int argc, char * argv[], null_stream &nullStream2) { + if (argc > 1) do + { + argv++; + argc--; + if (strncmp(*argv, "-s", 2) == 0 || + strncmp(*argv, "/s", 2) == 0) + { + std::cerr.rdbuf(&nullStream2); + return; + } + } while (argc > 1); +} + } // namespace pcm \ No newline at end of file diff --git a/utils.h b/utils.h index 484e18cd..9b5fd220 100644 --- a/utils.h +++ b/utils.h @@ -474,4 +474,8 @@ inline HANDLE openMSRDriver() } #endif +// called before everything else to read '-s' arg and +// silence all following err output +void check_and_set_silent(int argc, char * argv[], null_stream &nullStream2); + } // namespace pcm From c716f09dbad9f7105544f62298e0cdece1508851 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Thu, 2 Dec 2021 05:32:43 +0100 Subject: [PATCH 02/12] add client metrics to csv --- pcm.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pcm.cpp b/pcm.cpp index 4f20b197..21c83076 100644 --- a/pcm.cpp +++ b/pcm.cpp @@ -465,12 +465,11 @@ void print_output(PCM * m, if (m->MCDRAMmemoryTrafficMetricsAvailable()) cout << " " << setw(11) << getBytesReadFromEDC(sktstate1[i], sktstate2[i]) / double(1e9) << " " << setw(11) << getBytesWrittenToEDC(sktstate1[i], sktstate2[i]) / double(1e9); - if (m->memoryIOTrafficMetricAvailable()) + if (m->memoryIOTrafficMetricAvailable()) { cout << " " << setw(5) << getIORequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); - if (m->memoryIOTrafficMetricAvailable()) cout << " " << setw(5) << getIARequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); - if (m->memoryIOTrafficMetricAvailable()) cout << " " << setw(5) << getGTRequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); + } cout << " "; if(m->packageEnergyMetricsAvailable()) { cout << setw(6) << getConsumedJoules(sktstate1[i], sktstate2[i]); @@ -649,6 +648,8 @@ void print_csv_header(PCM * m, print_csv_header_helper(header,2); if (m->MCDRAMmemoryTrafficMetricsAvailable()) print_csv_header_helper(header,2); + if (m->memoryIOTrafficMetricAvailable()) + print_csv_header_helper(header,3); print_csv_header_helper(header,7); //ACYC,TIME(ticks),PhysIPC,PhysIPC%,INSTnom,INSTnom%, } @@ -807,6 +808,8 @@ void print_csv_header(PCM * m, cout << "PMM_RD,PMM_WR,"; if (m->MCDRAMmemoryTrafficMetricsAvailable()) cout << "MCDRAM_READ,MCDRAM_WRITE,"; + if (m->memoryIOTrafficMetricAvailable()) + cout << "IO,IA,GT,"; cout << "TEMP,"; cout << "INST,ACYC,TIME(ticks),PhysIPC,PhysIPC%,INSTnom,INSTnom%,"; } @@ -1027,6 +1030,11 @@ void print_csv(PCM * m, if (m->MCDRAMmemoryTrafficMetricsAvailable()) cout << ',' << getBytesReadFromEDC(sktstate1[i], sktstate2[i]) / double(1e9) << ',' << getBytesWrittenToEDC(sktstate1[i], sktstate2[i]) / double(1e9); + if (m->memoryIOTrafficMetricAvailable()) { + cout << ',' << getIORequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9) + << ',' << getIARequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9) + << ',' << getGTRequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); + } cout << ',' << temp_format(sktstate2[i].getThermalHeadroom()) << ','; cout << float_format(getInstructionsRetired(sktstate1[i], sktstate2[i])) << "," From 2293529540f2254abaf62004c9a15005bf75bcb4 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Fri, 3 Dec 2021 02:19:56 +0100 Subject: [PATCH 03/12] add -i option to pcm-iio.cpp --- pcm-iio.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pcm-iio.cpp b/pcm-iio.cpp index 591fb9c5..943c3b8b 100644 --- a/pcm-iio.cpp +++ b/pcm-iio.cpp @@ -1122,8 +1122,9 @@ void print_usage(const string& progname) << " to a file, in case filename is provided\n"; cerr << " -csv-delimiter= | /csv-delimiter= => set custom csv delimiter\n"; cerr << " -human-readable | /human-readable => use human readable format for output (for csv only)\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; cerr << " Examples:\n"; - cerr << " " << progname << " 1.0 => print counters every second\n"; + cerr << " " << progname << " 1.0 -i=10 => print counters every second 10 times and exit\n"; cerr << " " << progname << " 0.5 -csv=test.log => twice a second save counter values to test.log in CSV format\n"; cerr << " " << progname << " -csv -human-readable => every 3 second print counters in human-readable CSV format\n"; cerr << "\n"; @@ -1145,6 +1146,7 @@ int main(int argc, char * argv[]) std::string csv_delimiter = ","; std::string output_file; double delay = PCM_DELAY_DEFAULT; + MainLoop mainLoop; PCM * m = PCM::getInstance(); while (argc > 1) { @@ -1168,6 +1170,9 @@ int main(int argc, char * argv[]) else if (check_argument_equals(*argv, {"-human-readable", "/human-readable"})) { human_readable = true; } + else if (mainLoop.parseArg(*argv)) { + continue; + } else { // any other options positional that is a floating point number is treated as , // while the other options are ignored with a warning issues to stderr @@ -1252,11 +1257,15 @@ int main(int argc, char * argv[]) output = &file_stream; } - while (1) { + mainLoop([&]() + { collect_data(m, delay, iios, counters); vector display_buffer = csv ? build_csv(iios, counters, human_readable, csv_delimiter) : build_display(iios, counters, pciDB); display(display_buffer, *output); - }; + return true; + }); + + exit(EXIT_SUCCESS); } From aba8b10389bd6252a2ab62f5d09fafa65b2bf798 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 3 Dec 2021 08:41:08 +0100 Subject: [PATCH 04/12] don't use perf API for uncore if uncore perf iMC interface is not available --- cpucounters.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpucounters.cpp b/cpucounters.cpp index d8285c7b..3aa8fd4a 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -5641,6 +5641,11 @@ bool PCM::useLinuxPerfForUncore() const #ifdef PCM_USE_PERF const auto imcIDs = enumeratePerfPMUs("imc", 100); std::cerr << "INFO: Linux perf interface to program uncore PMUs is " << (imcIDs.empty()?"NOT ":"") << "present\n"; + if (imcIDs.empty()) + { + use = 0; + return 1 == use; + } const char * perf_env = std::getenv("PCM_USE_UNCORE_PERF"); if (perf_env != NULL && std::string(perf_env) == std::string("1")) { @@ -7682,6 +7687,7 @@ void PCM::programCbo(const uint64 * events, const uint32 opCode, const uint32 nc for(uint32 cbo = 0; cbo < getMaxNumOfCBoxes(); ++cbo) { + assert(cbo < cboPMUs[i].size()); cboPMUs[i][cbo].initFreeze(UNC_PMON_UNIT_CTL_FRZ_EN); if (ICX != cpu_model && SNOWRIDGE != cpu_model) From 8e4f027b658c6c0ed313865cdfeb3d21c390e477 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Wed, 8 Dec 2021 04:45:45 +0100 Subject: [PATCH 05/12] Fix header in tab separated prints --- pcm-raw.cpp | 4 ++-- utils.h | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pcm-raw.cpp b/pcm-raw.cpp index 6354970e..b2ac206b 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -907,12 +907,12 @@ void print(const PCM::RawPMUConfigs& curPMUConfigs, PCM* m, vector 0 && AfterState.size() > 0) { choose(outputType, []() { cout << separator; }, - []() { cout << "ms,"; }, + []() { cout << "ms" << separator; }, [&]() { cout << (1000ULL * getInvariantTSC(BeforeState[0], AfterState[0])) / m->getNominalFrequency() << separator; }); } for (auto typeEvents : curPMUConfigs) diff --git a/utils.h b/utils.h index 9b5fd220..680b6b8a 100644 --- a/utils.h +++ b/utils.h @@ -258,25 +258,27 @@ inline void choose(const CsvOutputType outputType, H1 h1Func, H2 h2Func, D dataF } } -inline void printDateForCSV(const CsvOutputType outputType) +inline void printDateForCSV(const CsvOutputType outputType, std::string separator = std::string(",")) { choose(outputType, - []() { - std::cout << ",,"; // Time + [&separator]() { + std::cout << separator << separator; // Time }, - []() { std::cout << "Date,Time,"; }, - []() { + [&separator]() { + std::cout << "Date" << separator << "Time" << separator; + }, + [&separator]() { std::pair tt{ pcm_localtime() }; std::cout.precision(3); char old_fill = std::cout.fill('0'); std::cout << std::setw(4) << 1900 + tt.first.tm_year << '-' << std::setw(2) << 1 + tt.first.tm_mon << '-' << - std::setw(2) << tt.first.tm_mday << ',' << + std::setw(2) << tt.first.tm_mday << separator << std::setw(2) << tt.first.tm_hour << ':' << std::setw(2) << tt.first.tm_min << ':' << std::setw(2) << tt.first.tm_sec << '.' << - std::setw(3) << tt.second << ','; // milliseconds + std::setw(3) << tt.second << separator; // milliseconds std::cout.fill(old_fill); std::cout.setf(std::ios::fixed); std::cout.precision(2); From 807145a36cd14026285f85ec6981ba50d3977c85 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Fri, 3 Dec 2021 07:13:46 +0100 Subject: [PATCH 06/12] Add update option --- pcm-memory.cpp | 22 +++++++++++++++++----- utils.h | 7 +++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pcm-memory.cpp b/pcm-memory.cpp index cdef9283..7292070b 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -102,6 +102,7 @@ void print_help(const string prog_name) cerr << " -all | /all => Display all channels (even with no traffic)\n"; cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; cerr << " -s => silence information output and print only measurements\n"; + cerr << " -u => update measurements instead of printing new ones\n"; #ifdef _MSC_VER cerr << " --uninstallDriver | --installDriver=> (un)install driver\n"; #endif @@ -364,7 +365,7 @@ void printSocketBWFooter(uint32 no_columns, uint32 skt, const memdata_t *md) cout << "\n"; } -void display_bandwidth(PCM *m, memdata_t *md, const uint32 no_columns, const bool show_channel_output) +void display_bandwidth(PCM *m, memdata_t *md, const uint32 no_columns, const bool show_channel_output, const bool print_update) { float sysReadDRAM = 0.0, sysWriteDRAM = 0.0, sysReadPMM = 0.0, sysWritePMM = 0.0; uint32 numSockets = m->getNumSockets(); @@ -372,6 +373,9 @@ void display_bandwidth(PCM *m, memdata_t *md, const uint32 no_columns, const boo cout.setf(ios::fixed); cout.precision(2); + if (print_update) + clear_screen(); + while (skt < numSockets) { auto printRow = [&skt,&show_channel_output,&m,&md,&sysReadDRAM,&sysWriteDRAM, &sysReadPMM, &sysWritePMM](const uint32 no_columns) @@ -733,7 +737,8 @@ void calculate_bandwidth(PCM *m, bool & csvheader, uint32 no_columns, const ServerUncoreMemoryMetrics & metrics, - const bool show_channel_output) + const bool show_channel_output, + const bool print_update) { //const uint32 num_imc_channels = m->getMCChannelsPerSocket(); //const uint32 num_edc_channels = m->getEDCChannelsPerSocket(); @@ -926,7 +931,7 @@ void calculate_bandwidth(PCM *m, } else { - display_bandwidth(m, &md, no_columns, show_channel_output); + display_bandwidth(m, &md, no_columns, show_channel_output, print_update); } } @@ -984,7 +989,7 @@ int main(int argc, char * argv[]) cerr << "\n"; double delay = -1.0; - bool csv = false, csvheader=false, show_channel_output=true; + bool csv = false, csvheader = false, show_channel_output = true, print_update = false; uint32 no_columns = DEFAULT_DISPLAY_COLUMNS; // Default number of columns is 2 char * sysCmd = NULL; char ** sysArgv = NULL; @@ -1110,6 +1115,12 @@ int main(int argc, char * argv[]) //already checked by check_and_set_silent() continue; } + else if (strncmp(*argv, "-u", 2) == 0 || + strncmp(*argv, "/u", 2) == 0) + { + print_update = true; + continue; + } #ifdef _MSC_VER else if (strncmp(*argv, "--uninstallDriver", 17) == 0) { @@ -1243,7 +1254,8 @@ int main(int argc, char * argv[]) if(rankA >= 0 || rankB >= 0) calculate_bandwidth_rank(m,BeforeState,AfterState,AfterTime-BeforeTime,csv,csvheader, no_columns, rankA, rankB); else - calculate_bandwidth(m,BeforeState,AfterState,AfterTime-BeforeTime,csv,csvheader, no_columns, metrics, show_channel_output); + calculate_bandwidth(m,BeforeState,AfterState,AfterTime-BeforeTime,csv,csvheader, no_columns, metrics, + show_channel_output, print_update); swap(BeforeTime, AfterTime); swap(BeforeState, AfterState); diff --git a/utils.h b/utils.h index 9b5fd220..3c6d6d4e 100644 --- a/utils.h +++ b/utils.h @@ -391,6 +391,13 @@ inline void pcm_cpuid(int leaf, PCM_CPUID_INFO& info) #endif } +inline void clear_screen() { +#ifdef _MSC_VER + system("cls"); +#else + std::cout << "\033[2J\033[0;0H"; +#endif +} inline uint32 build_bit_ui(uint32 beg, uint32 end) { From 6eae15eae579489393aa08ca316df1a814cd7614 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 10 Dec 2021 15:10:39 +0100 Subject: [PATCH 07/12] free winring0 using DeinitOpenLibSys Change-Id: I30d96cd86d168a6d1b8ee3d79499565deab800c1 --- cpucounters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpucounters.cpp b/cpucounters.cpp index 3aa8fd4a..815ff9b0 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -112,7 +112,7 @@ bool PCM::initWinRing0Lib() if (result == FALSE) { - CloseHandle(hOpenLibSys); + DeinitOpenLibSys(&hOpenLibSys); hOpenLibSys = NULL; return false; } From fe9655c9cb5697694f2151e4a1e4159db20af06f Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 10 Dec 2021 15:52:32 +0100 Subject: [PATCH 08/12] pcm-raw: overhead reduction for single group collection Change-Id: Iadb188bc1c8b38e3670afbeeaff9f59e0bfdd8a1 --- pcm-raw.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/pcm-raw.cpp b/pcm-raw.cpp index 6354970e..4d9ef1fd 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -1346,12 +1346,21 @@ int main(int argc, char* argv[]) { if (!group.empty()) ++nGroups; } + for (size_t i = 0; i < PMUConfigs.size(); ++i) + { + if (PMUConfigs[i].empty()) + { // erase empty groups + PMUConfigs.erase(PMUConfigs.begin() + i); + --i; + } + } + assert(PMUConfigs.size() == nGroups); if (nGroups == 0) { cout << "No events specified. Exiting.\n"; exit(EXIT_FAILURE); } - cout << "Collecting " << nGroups << " event groups\n"; + cout << "Collecting " << nGroups << " event group(s)\n"; if (nGroups > 1) { @@ -1393,20 +1402,34 @@ int main(int argc, char* argv[]) MySystem(sysCmd, sysArgv); } + auto programAndReadGroup = [&](const PCM::RawPMUConfigs & group) + { + if (forceRTMAbortMode) + { + m->enableForceRTMAbortMode(true); + } + programPMUs(group); + m->getAllCounterStates(SysBeforeState, DummySocketStates, BeforeState); + for (uint32 s = 0; s < m->getNumSockets(); ++s) + { + BeforeUncoreState[s] = m->getServerUncoreCounterState(s); + } + }; + + if (nGroups == 1) + { + programAndReadGroup(PMUConfigs[0]); + } + mainLoop([&]() { - for (const auto group : PMUConfigs) + for (const auto & group : PMUConfigs) { if (group.empty()) continue; - if (forceRTMAbortMode) - { - m->enableForceRTMAbortMode(true); - } - programPMUs(group); - m->getAllCounterStates(SysBeforeState, DummySocketStates, BeforeState); - for (uint32 s = 0; s < m->getNumSockets(); ++s) + + if (nGroups > 1) { - BeforeUncoreState[s] = m->getServerUncoreCounterState(s); + programAndReadGroup(group); } calibratedSleep(delay, sysCmd, mainLoop, m); @@ -1421,7 +1444,15 @@ int main(int argc, char* argv[]) //cout << "Called sleep function for " << dec << fixed << delay_ms << " ms\n"; printAll(group, m, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState); - m->cleanup(true); + if (nGroups > 1) + { + m->cleanup(true); + } + else + { + std::swap(BeforeState, AfterState); + std::swap(BeforeUncoreState, AfterUncoreState); + } } if (m->isBlocked()) { // in case PCM was blocked after spawning child application: break monitoring loop here From 85cc23dfb1c8c956262f88d3d616a21115808608 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 10 Dec 2021 16:00:18 +0100 Subject: [PATCH 09/12] pcm-iio: add a test Change-Id: I50e1769cb330c18d88ea41b7a418721b611da630 --- test.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test.sh b/test.sh index 8f773779..51bb96d0 100644 --- a/test.sh +++ b/test.sh @@ -24,6 +24,12 @@ if [ "$?" -ne "0" ]; then exit 1 fi +./pcm-iio.x -i=1 +if [ "$?" -ne "0" ]; then + echo "Error in pcm-iio.x" + exit 1 +fi + ./pcm-raw.x -e core/config=0x30203,name=LD_BLOCKS.STORE_FORWARD/ -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS -- sleep 1 if [ "$?" -ne "0" ]; then echo "Error in pcm-raw.x" @@ -97,7 +103,7 @@ if [ "$?" -ne "0" ]; then fi # TODO add more tests -# e.g for ./pcm-sensor-server.x, ./pcm-iio.x, ./pcm-sensor.x, ... +# e.g for ./pcm-sensor-server.x, ./pcm-sensor.x, ... pushd unitTest/ make From 404cf77c6e72323d5a66e5d9f9bba9aeda013519 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Wed, 15 Dec 2021 08:22:38 -0700 Subject: [PATCH 10/12] robustness enhancements --- c_example.c | 2 +- cpucounters.cpp | 37 +++++++++++++++++++++-------------- cpucounters.h | 8 ++++++-- daemon/daemon/daemon.cpp | 10 ++++++---- daemon/daemon/daemon.h | 4 ++-- lspci.h | 24 +++++++++++------------ pci.cpp | 6 +++--- pcm-iio.cpp | 6 +++--- pcm-lspci.cpp | 1 + pcm-memory.cpp | 42 ++++++++++++++++++++-------------------- pcm-msr.cpp | 1 + pcm-pcicfg.cpp | 1 + pcm-power.cpp | 4 +++- pcm-sensor-server.cpp | 24 +++++++++++++++++------ utils.h | 16 +++++++-------- 15 files changed, 108 insertions(+), 78 deletions(-) diff --git a/c_example.c b/c_example.c index d53768a0..77f680d7 100644 --- a/c_example.c +++ b/c_example.c @@ -78,7 +78,7 @@ int main(int argc, const char *argv[]) if(PCM.pcm_c_init == NULL || PCM.pcm_c_start == NULL || PCM.pcm_c_stop == NULL || PCM.pcm_c_get_cycles == NULL || PCM.pcm_c_get_instr == NULL || - PCM.pcm_c_build_core_event == NULL) + PCM.pcm_c_build_core_event == NULL || PCM.pcm_c_get_core_event == NULL) return -1; switch(argc-1) { diff --git a/cpucounters.cpp b/cpucounters.cpp index 815ff9b0..f6598e9b 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -220,6 +220,7 @@ class TemporalThreadAffinity // speedup trick for Linux, FreeBSD, DragonFlyBSD, public: TemporalThreadAffinity(uint32 core_id, bool checkStatus = true) { + assert(core_id < 1024); pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &old_affinity); cpu_set_t new_affinity; @@ -247,6 +248,7 @@ class TemporalThreadAffinity // speedup trick for Linux, FreeBSD, DragonFlyBSD, TemporalThreadAffinity(const uint32 core_id, bool checkStatus = true) : set_size(CPU_ALLOC_SIZE(maxCPUs)) { + assert(core_id < maxCPUs); old_affinity = CPU_ALLOC(maxCPUs); assert(old_affinity); pthread_getaffinity_np(pthread_self(), set_size, old_affinity); @@ -593,7 +595,7 @@ bool PCM::detectModel() auto tokens = split(line, ':'); if (tokens.size() >= 2 && tokens[0].find("flags") == 0) { - for (auto curFlag : split(tokens[1], ' ')) + for (const auto & curFlag : split(tokens[1], ' ')) { if (flag == curFlag) { @@ -3046,18 +3048,21 @@ PCM::ErrorCode PCM::programCoreCounters(const int i /* core */, perf_event_attr e = PCM_init_perf_event_attr(); e.type = PERF_TYPE_RAW; e.config = (1ULL << 63ULL) + event_select_reg.value; - if (event_select_reg.fields.event_select == getOCREventNr(0, i).first && event_select_reg.fields.umask == getOCREventNr(0, i).second) - e.config1 = pExtDesc->OffcoreResponseMsrValue[0]; - if (event_select_reg.fields.event_select == getOCREventNr(1, i).first && event_select_reg.fields.umask == getOCREventNr(1, i).second) - e.config1 = pExtDesc->OffcoreResponseMsrValue[1]; - - if (event_select_reg.fields.event_select == LOAD_LATENCY_EVTNR && event_select_reg.fields.umask == LOAD_LATENCY_UMASK) - { - e.config1 = pExtDesc->LoadLatencyMsrValue; - } - if (event_select_reg.fields.event_select == FRONTEND_EVTNR && event_select_reg.fields.umask == FRONTEND_UMASK) + if (pExtDesc != nullptr) { - e.config1 = pExtDesc->FrontendMsrValue; + if (event_select_reg.fields.event_select == getOCREventNr(0, i).first && event_select_reg.fields.umask == getOCREventNr(0, i).second) + e.config1 = pExtDesc->OffcoreResponseMsrValue[0]; + if (event_select_reg.fields.event_select == getOCREventNr(1, i).first && event_select_reg.fields.umask == getOCREventNr(1, i).second) + e.config1 = pExtDesc->OffcoreResponseMsrValue[1]; + + if (event_select_reg.fields.event_select == LOAD_LATENCY_EVTNR && event_select_reg.fields.umask == LOAD_LATENCY_UMASK) + { + e.config1 = pExtDesc->LoadLatencyMsrValue; + } + if (event_select_reg.fields.event_select == FRONTEND_EVTNR && event_select_reg.fields.umask == FRONTEND_UMASK) + { + e.config1 = pExtDesc->FrontendMsrValue; + } } if (programPerfEvent(e, PERF_GEN_EVENT_0_POS + j, std::string("generic event #") + std::to_string(i)) == false) @@ -3113,12 +3118,12 @@ PCM::ErrorCode PCM::programCoreCounters(const int i /* core */, std::make_pair(perfRetiringPath, PERF_TOPDOWN_RETIRING_POS)}; int readPos = core_fixed_counter_num_used + core_gen_counter_num_used; leader_counter = -1; - for (auto event : topDownEvents) + for (const auto & event : topDownEvents) { uint64 eventSel = 0, umask = 0; const auto eventDesc = readSysFS(event.first); const auto tokens = split(eventDesc, ','); - for (auto token : tokens) + for (const auto & token : tokens) { if (match(token, "event=", &eventSel)) { @@ -4605,7 +4610,7 @@ PCM::ErrorCode PCM::program(const RawPMUConfigs& curPMUConfigs_, const bool sile else { fixedReg.value = 0; - for (auto cfg : corePMUConfig.fixed) + for (const auto & cfg : corePMUConfig.fixed) { fixedReg.value |= cfg.first[0]; } @@ -5428,6 +5433,7 @@ void print_mcfg(const char * path) if(read_bytes == 0) { std::cerr << "PCM Error: Cannot read " << path << "\n"; + ::close(mcfg_handle); throw std::exception(); } @@ -5442,6 +5448,7 @@ void print_mcfg(const char * path) if(read_bytes == 0) { std::cerr << "PCM Error: Cannot read " << path << " (2)\n"; + ::close(mcfg_handle); throw std::exception(); } std::cout << "Segment " << std::dec << i << " "; diff --git a/cpucounters.h b/cpucounters.h index 5f4f8a72..487e405c 100644 --- a/cpucounters.h +++ b/cpucounters.h @@ -2934,6 +2934,7 @@ class CoreCounterState : public BasicCounterState CoreCounterState( const CoreCounterState& ) = default; CoreCounterState( CoreCounterState&& ) = default; CoreCounterState & operator= ( CoreCounterState&& ) = default; + virtual ~ CoreCounterState() {} }; //! \brief Socket-wide counter state @@ -2972,6 +2973,8 @@ class SocketCounterState : public BasicCounterState, public UncoreCounterState UncoreCounterState::operator = ( std::move(ucs) ); return *this; } + + virtual ~ SocketCounterState() {} }; //! \brief System-wide counter state @@ -3028,6 +3031,7 @@ class SystemCounterState : public SocketCounterState return *this; } + virtual ~ SystemCounterState() {} }; /*! \brief Reads the counter state of the system @@ -3977,11 +3981,11 @@ inline uint64 getNumberOfEvents(const CounterType & before, const CounterType & template inline double getLLCReadMissLatency(const CounterStateType & before, const CounterStateType & after) { - if (PCM::getInstance()->LLCReadMissLatencyMetricsAvailable() == false) return -1.; + auto * m = PCM::getInstance(); + if (m->LLCReadMissLatencyMetricsAvailable() == false) return -1.; const double occupancy = double(after.TOROccupancyIAMiss) - double(before.TOROccupancyIAMiss); const double inserts = double(after.TORInsertsIAMiss) - double(before.TORInsertsIAMiss); const double unc_clocks = double(after.UncClocks) - double(before.UncClocks); - auto * m = PCM::getInstance(); const double seconds = double(getInvariantTSC(before, after)) / double(m->getNumOnlineCores()/m->getNumSockets()) / double(m->getNominalFrequency()); return 1e9*seconds*(occupancy/inserts)/unc_clocks; } diff --git a/daemon/daemon/daemon.cpp b/daemon/daemon/daemon.cpp index af4dbe59..601a4de1 100644 --- a/daemon/daemon/daemon.cpp +++ b/daemon/daemon/daemon.cpp @@ -55,7 +55,9 @@ namespace PCMDaemon { //Put the poll interval in shared memory so that the client knows sharedPCMState_->pollMs = pollIntervalMs_; - updatePCMState(&systemStatesBefore_, &socketStatesBefore_, &coreStatesBefore_); + collectionTimeAfter_ = 0; + + updatePCMState(&systemStatesBefore_, &socketStatesBefore_, &coreStatesBefore_, collectionTimeBefore_); systemStatesForQPIBefore_ = SystemCounterState(systemStatesBefore_); serverUncoreCounterStatesBefore_ = new ServerUncoreCounterState[pcmInstance_->getNumSockets()]; @@ -384,7 +386,7 @@ namespace PCMDaemon { sharedPCMState_->lastUpdateTscBegin = RDTSC(); - updatePCMState(&systemStatesAfter_, &socketStatesAfter_, &coreStatesAfter_); + updatePCMState(&systemStatesAfter_, &socketStatesAfter_, &coreStatesAfter_, collectionTimeAfter_); getPCMSystem(); @@ -421,7 +423,7 @@ namespace PCMDaemon { std::swap(collectionTimeBefore_, collectionTimeAfter_); } - void Daemon::updatePCMState(SystemCounterState* systemStates, std::vector* socketStates, std::vector* coreStates) + void Daemon::updatePCMState(SystemCounterState* systemStates, std::vector* socketStates, std::vector* coreStates, uint64 & t) { if(subscribers_.find("core") != subscribers_.end()) { @@ -434,7 +436,7 @@ namespace PCMDaemon { pcmInstance_->getUncoreCounterStates(*systemStates, *socketStates); } } - collectionTimeAfter_ = pcmInstance_->getTickCount(); + t = pcmInstance_->getTickCount(); } void Daemon::swapPCMBeforeAfterState() diff --git a/daemon/daemon/daemon.h b/daemon/daemon/daemon.h index 124c6d9e..baf13686 100644 --- a/daemon/daemon/daemon.h +++ b/daemon/daemon/daemon.h @@ -42,7 +42,7 @@ namespace PCMDaemon { void setupSharedMemory(); gid_t resolveGroupName(const std::string& groupName); void getPCMCounters(); - void updatePCMState(SystemCounterState* systemStates, std::vector* socketStates, std::vector* coreStates); + void updatePCMState(SystemCounterState* systemStates, std::vector* socketStates, std::vector* coreStates, uint64 & t); void swapPCMBeforeAfterState(); void getPCMSystem(); void getPCMCore(); @@ -64,7 +64,7 @@ namespace PCMDaemon { std::vector allowedSubscribers_; //Data for core, socket and system state - uint64 collectionTimeBefore_, collectionTimeAfter_; + uint64 collectionTimeBefore_{0ULL}, collectionTimeAfter_{0ULL}; std::vector coreStatesBefore_, coreStatesAfter_; std::vector socketStatesBefore_, socketStatesAfter_; SystemCounterState systemStatesBefore_, systemStatesForQPIBefore_, systemStatesAfter_; diff --git a/lspci.h b/lspci.h index eaa6cde2..31a0cd40 100644 --- a/lspci.h +++ b/lspci.h @@ -272,13 +272,13 @@ struct iio_skx { struct { struct pci root_pci_dev; /* single device represent root port */ std::vector child_pci_devs; /* Contain child switch and end-point devices */ - } parts[4]; /* part 0, 1, 2, 3 */ - uint8_t busno; /* holding busno for each IIO stack */ - std::string stack_name; - std::vector values; + } parts[4]{}; /* part 0, 1, 2, 3 */ + uint8_t busno{}; /* holding busno for each IIO stack */ + std::string stack_name{}; + std::vector values{}; bool flipped = false; } stacks[6]; /* iio stack 0, 1, 2, 3, 4, 5 */ - uint32_t socket_id; + uint32_t socket_id{}; }; struct iio_bifurcated_part { @@ -290,13 +290,13 @@ struct iio_bifurcated_part { }; struct iio_stack { - std::vector parts; - uint32_t iio_unit_id; - std::string stack_name; - std::vector values; + std::vector parts{}; + uint32_t iio_unit_id{}; + std::string stack_name{}; + std::vector values{}; bool flipped = false; /* holding busno for each IIO stack */ - uint8_t busno; + uint8_t busno{}; }; bool operator<(const iio_stack& lh, const iio_stack& rh) @@ -305,8 +305,8 @@ bool operator<(const iio_stack& lh, const iio_stack& rh) } struct iio_stacks_on_socket { - std::vector stacks; - uint32_t socket_id; + std::vector stacks{}; + uint32_t socket_id{}; }; bool operator < (const bdf &l, const bdf &r) { diff --git a/pci.cpp b/pci.cpp index 1de73795..060bacb7 100644 --- a/pci.cpp +++ b/pci.cpp @@ -447,12 +447,12 @@ PciHandle::~PciHandle() int PciHandle::openMcfgTable() { const std::vector base_paths = {"/sys/firmware/acpi/tables/MCFG", "/sys/firmware/acpi/tables/MCFG1"}; std::vector paths = base_paths; - for (auto p: base_paths) + for (const auto & p: base_paths) { paths.push_back(std::string("/pcm") + p); } int handle = -1; - for (auto p: paths) + for (const auto & p: paths) { if (handle < 0) { @@ -461,7 +461,7 @@ int PciHandle::openMcfgTable() { } if (handle < 0) { - for (auto p: paths) + for (const auto & p: paths) { std::cerr << "Can't open MCFG table. Check permission of " << p << "\n"; } diff --git a/pcm-iio.cpp b/pcm-iio.cpp index 943c3b8b..7d56b0ee 100644 --- a/pcm-iio.cpp +++ b/pcm-iio.cpp @@ -876,7 +876,7 @@ ccr* get_ccr(PCM* m, uint64_t& ccr) vector load_events(PCM * m, const char* fn) { vector v; - struct counter ctr; + struct counter ctr{}; std::unique_ptr pccr(get_ccr(m, ctr.ccr)); std::ifstream in(fn); @@ -1055,9 +1055,9 @@ void print_PCIeMapping(const std::vector& iios, con for (auto it = iios.begin(); it != iios.end(); ++it) { printf("Socket %d\n", (*it).socket_id); for (int stack = 0; stack < 6; stack++) { - for (auto stack : it->stacks) { + for (auto & stack : it->stacks) { printf("\t%s root bus: 0x%x", stack.stack_name.c_str(), stack.busno); - printf(stack.flipped ? "\tflipped: true\n" : "\tflipped: false\n"); + printf("\tflipped: %s\n", stack.flipped ? "true" : "false"); for (auto part : stack.parts) { vector pp = part.child_pci_devs; uint8_t level = 1; diff --git a/pcm-lspci.cpp b/pcm-lspci.cpp index 1b2bbc25..ccad6557 100644 --- a/pcm-lspci.cpp +++ b/pcm-lspci.cpp @@ -117,4 +117,5 @@ int main(int /*argc*/, char * /*argv*/[]) std::cout << "\n Display PCI tree information\n\n"; for(int bus=0; bus < 256; ++bus) scanBus(bus, pciDB); + return 0; } diff --git a/pcm-memory.cpp b/pcm-memory.cpp index 7292070b..f79aab78 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -51,27 +51,27 @@ const uint32 max_edc_channels = ServerUncoreCounterState::maxChannels; const uint32 max_imc_controllers = ServerUncoreCounterState::maxControllers; typedef struct memdata { - float iMC_Rd_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]; - float iMC_Wr_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]; - float iMC_PMM_Rd_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]; - float iMC_PMM_Wr_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]; - float iMC_PMM_MemoryMode_Miss_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]; - float iMC_Rd_socket[max_sockets]; - float iMC_Wr_socket[max_sockets]; - float iMC_PMM_Rd_socket[max_sockets]; - float iMC_PMM_Wr_socket[max_sockets]; - float iMC_PMM_MemoryMode_Miss_socket[max_sockets]; - bool iMC_NM_hit_rate_supported; - float iMC_PMM_MemoryMode_Hit_socket[max_sockets]; - bool M2M_NM_read_hit_rate_supported; - float iMC_NM_hit_rate[max_sockets]; - float M2M_NM_read_hit_rate[max_sockets][max_imc_controllers]; - float EDC_Rd_socket_chan[max_sockets][max_edc_channels]; - float EDC_Wr_socket_chan[max_sockets][max_edc_channels]; - float EDC_Rd_socket[max_sockets]; - float EDC_Wr_socket[max_sockets]; - uint64 partial_write[max_sockets]; - ServerUncoreMemoryMetrics metrics; + float iMC_Rd_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]{}; + float iMC_Wr_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]{}; + float iMC_PMM_Rd_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]{}; + float iMC_PMM_Wr_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]{}; + float iMC_PMM_MemoryMode_Miss_socket_chan[max_sockets][ServerUncoreCounterState::maxChannels]{}; + float iMC_Rd_socket[max_sockets]{}; + float iMC_Wr_socket[max_sockets]{}; + float iMC_PMM_Rd_socket[max_sockets]{}; + float iMC_PMM_Wr_socket[max_sockets]{}; + float iMC_PMM_MemoryMode_Miss_socket[max_sockets]{}; + bool iMC_NM_hit_rate_supported{}; + float iMC_PMM_MemoryMode_Hit_socket[max_sockets]{}; + bool M2M_NM_read_hit_rate_supported{}; + float iMC_NM_hit_rate[max_sockets]{}; + float M2M_NM_read_hit_rate[max_sockets][max_imc_controllers]{}; + float EDC_Rd_socket_chan[max_sockets][max_edc_channels]{}; + float EDC_Wr_socket_chan[max_sockets][max_edc_channels]{}; + float EDC_Rd_socket[max_sockets]{}; + float EDC_Wr_socket[max_sockets]{}; + uint64 partial_write[max_sockets]{}; + ServerUncoreMemoryMetrics metrics{}; } memdata_t; bool anyPmem(const ServerUncoreMemoryMetrics & metrics) diff --git a/pcm-msr.cpp b/pcm-msr.cpp index cd121e1f..833e52f1 100644 --- a/pcm-msr.cpp +++ b/pcm-msr.cpp @@ -143,4 +143,5 @@ int main(int argc, char * argv[]) } } } + return 0; } diff --git a/pcm-pcicfg.cpp b/pcm-pcicfg.cpp index ff8f5703..c33e139e 100644 --- a/pcm-pcicfg.cpp +++ b/pcm-pcicfg.cpp @@ -115,4 +115,5 @@ int main(int argc, char * argv[]) std::cerr << "Error accessing registers: " << e.what() << "\n"; std::cerr << "Please check if the program can access MSR/PCICFG drivers.\n"; } + return 0; } diff --git a/pcm-power.cpp b/pcm-power.cpp index 6b617876..95aaae5d 100644 --- a/pcm-power.cpp +++ b/pcm-power.cpp @@ -355,7 +355,9 @@ int main(int argc, char * argv[]) all += getNumberOfCustomEvents(l, before, after); } assert(license < nCorePowerLicenses); - return 100.0 * double(getNumberOfCustomEvents(license, before, after)) / double(all); + if (all > 0) + return 100.0 * double(getNumberOfCustomEvents(license, before, after)) / double(all); + return -1.; }; const auto uncoreFreqFactor = double(m->getNumOnlineSockets()) / double(m->getNumOnlineCores()); diff --git a/pcm-sensor-server.cpp b/pcm-sensor-server.cpp index 295f3ee5..eae34f6a 100644 --- a/pcm-sensor-server.cpp +++ b/pcm-sensor-server.cpp @@ -122,7 +122,10 @@ class datetime { public: datetime() { std::time_t t = std::time( nullptr ); - now = *(std::gmtime( &t )); + const auto gt = std::gmtime( &t ); + if (gt == nullptr) + throw std::runtime_error("std::gmtime returned nullptr"); + now = *gt; } datetime( std::tm t ) : now( t ) {} ~datetime() = default; @@ -172,7 +175,9 @@ class date { public: void printDate( std::ostream& os ) const { char buf[64]; - std::strftime( buf, 64, "%F", std::localtime(&now) ); + const auto t = std::localtime(&now); + assert(t); + std::strftime( buf, 64, "%F", t); os << buf; } @@ -740,7 +745,7 @@ class PrometheusPrinter : Visitor if (hierarchy_.size() == 0 ) return s; s = "{"; - for( auto level : hierarchy_ ) { + for(const auto & level : hierarchy_ ) { s += level + ','; } s.pop_back(); @@ -1071,7 +1076,7 @@ typedef basic_socketstream wsocketstream; class Server { public: Server() = delete; - Server( std::string listenIP, uint16_t port ) noexcept( false ) : listenIP_(listenIP), port_( port ) { + Server( const std::string & listenIP, uint16_t port ) noexcept( false ) : listenIP_(listenIP), port_( port ) { serverSocket_ = initializeServerSocket(); SignalHandler* shi = SignalHandler::getInstance(); shi->setSocket( serverSocket_ ); @@ -1103,7 +1108,10 @@ class Server { serv.sin_addr.s_addr = INADDR_ANY; else { if ( 1 != ::inet_pton( AF_INET, listenIP_.c_str(), &(serv.sin_addr) ) ) + { + ::close(sockfd); throw std::runtime_error( "Server Constructor: Cannot convert IP string" ); + } } socklen_t len = sizeof( struct sockaddr_in ); retval = ::bind( sockfd, reinterpret_cast(&serv), len ); @@ -1122,7 +1130,7 @@ class Server { } protected: - std::string& listenIP_; + std::string listenIP_; WorkQueue wq_; int serverSocket_; uint16_t port_; @@ -2677,6 +2685,7 @@ void PeriodicCounterFetcher::execute() { auto before = steady_clock::now(); // create an aggregator std::shared_ptr sagp = std::make_shared(); + assert(sagp.get()); DBG( 2, "PCF::execute(): AGP=", sagp.get(), " )" ); // dispatch it sagp->dispatch( PCM::getInstance()->getSystemTopology() ); @@ -2718,11 +2727,12 @@ void HTTPServer::run() { int port = ntohs( clientAddress.sin_port ); DBG( 3, "Client IP is: ", ipbuf, ", and the port it uses is : ", port ); - HTTPConnection* connection; + HTTPConnection* connection = nullptr; try { connection = new HTTPConnection( this, clientSocketFD, clientAddress, callbackList_ ); } catch ( std::exception& e ) { DBG( 3, "Exception caught while creating a HTTPConnection: " ); + if (connection) delete connection; ::close( clientSocketFD ); continue; } @@ -2831,6 +2841,7 @@ inline constexpr signed char operator "" _uc( unsigned long long arg ) noexcept std::pair,std::shared_ptr> getNullAndCurrentAggregator() { std::shared_ptr current = std::make_shared(); std::shared_ptr null = std::make_shared(); + assert(current.get()); current->dispatch( PCM::getInstance()->getSystemTopology() ); return std::make_pair( null, current ); } @@ -3304,6 +3315,7 @@ int main( int argc, char* argv[] ) { DBG( 2, "Error forking. " ); return 200; } + return 0; } #endif // UNIT_TEST diff --git a/utils.h b/utils.h index 14b18099..f1a3f767 100644 --- a/utils.h +++ b/utils.h @@ -108,26 +108,26 @@ inline std::string unit_format(IntType n) if (n <= 9999ULL) { snprintf(buffer, 1024, "%4d ", int32(n)); - return buffer; + return std::string{buffer}; } if (n <= 9999999ULL) { snprintf(buffer, 1024, "%4d K", int32(n / 1000ULL)); - return buffer; + return std::string{buffer}; } if (n <= 9999999999ULL) { snprintf(buffer, 1024, "%4d M", int32(n / 1000000ULL)); - return buffer; + return std::string{buffer}; } if (n <= 9999999999999ULL) { snprintf(buffer, 1024, "%4d G", int32(n / 1000000000ULL)); - return buffer; + return std::string{buffer}; } snprintf(buffer, 1024, "%4d T", int32(n / (1000000000ULL * 1000ULL))); - return buffer; + return std::string{buffer}; } void print_cpu_details(); @@ -360,9 +360,9 @@ bool writeSysFS(const char * path, const std::string & value, bool silent); int calibratedSleep(const double delay, const char* sysCmd, const MainLoop& mainLoop, PCM* m); struct StackedBarItem { - double fraction; - std::string label; // not used currently - char fill; + double fraction{0.0}; + std::string label{""}; // not used currently + char fill{'0'}; StackedBarItem() {} StackedBarItem(double fraction_, const std::string & label_, From e2f78f4aa86721477e8727fd4e3af9570d216f88 Mon Sep 17 00:00:00 2001 From: Robert Dobrowolski Date: Fri, 10 Dec 2021 05:34:33 +0100 Subject: [PATCH 11/12] Add tsv event file support --- pcm-raw.cpp | 194 +++++++++++++++++++++++++++++++++++++++++++--------- test.sh | 93 +++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 31 deletions(-) diff --git a/pcm-raw.cpp b/pcm-raw.cpp index b2ac206b..e835f527 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -119,10 +119,60 @@ void lowerCase(std::string & str) using namespace simdjson; std::vector > JSONparsers; -std::unordered_map PMUEventMap; +std::unordered_map PMUEventMapJSON; +std::vector>> PMUEventMapsTSV; std::shared_ptr PMURegisterDeclarations; std::string eventFileLocationPrefix = "."; +bool parse_tsv(const string &path) { + bool col_names_parsed = false; + int event_name_pos = -1; + ifstream inFile; + string line; + inFile.open(path); + std::unordered_map> PMUEventMap; + + while (getline(inFile, line)) { + if (line.size() == 1 && line[0] == '\n') + continue; + // Trim whitespaces left/right // MOVE to utils + auto ws_left_count = 0; + for (size_t i = 0 ; i < line.size() ; i++) { + if (line[i] == ' ') ws_left_count++; + else break; + } + auto ws_right_count = 0; + for (size_t i = line.size() - 1 ; i > 0 ; i--) { + if (line[i] == ' ') ws_right_count++; + else break; + } + line.erase(0, ws_left_count); + line.erase(line.size() - ws_right_count, ws_right_count); + if (line[0] == '#') + continue; + if (!col_names_parsed) { + // Consider first row as Column name row + std::vector col_names = split(line, '\t'); + PMUEventMap["COL_NAMES"] = col_names; + const auto event_name_it = std::find(col_names.begin(), col_names.end(), "EventName"); + if (event_name_it == col_names.end()) { + cerr << "ERROR: First row does not contain EventName\n"; + inFile.close(); + return false; + } + event_name_pos = event_name_it - col_names.begin(); + col_names_parsed = true; + continue; + } + std::vector entry = split(line, '\t'); + std::string event_name = entry[event_name_pos]; + PMUEventMap[event_name] = entry; + } + inFile.close(); + PMUEventMapsTSV.push_back(PMUEventMap); + return true; +} + bool initPMUEventMap() { static bool inited = false; @@ -231,22 +281,30 @@ bool initPMUEventMap() return false; } - JSONparsers.push_back(std::make_shared()); - for (simdjson::dom::object eventObj : JSONparsers.back()->load(path)) { - // cout << "Event ----------------\n"; - const std::string EventName{eventObj["EventName"].get_c_str()}; - if (EventName.empty()) - { - cerr << "Did not find EventName in JSON object:\n"; - for (const auto keyValue : eventObj) + if (path.find(".json") != std::string::npos) { + JSONparsers.push_back(std::make_shared()); + for (simdjson::dom::object eventObj : JSONparsers.back()->load(path)) { + // cout << "Event ----------------\n"; + const std::string EventName{eventObj["EventName"].get_c_str()}; + if (EventName.empty()) + { + cerr << "Did not find EventName in JSON object:\n"; + for (const auto keyValue : eventObj) + { + cout << "key: " << keyValue.key << " value: " << keyValue.value << "\n"; + } + } + else { - cout << "key: " << keyValue.key << " value: " << keyValue.value << "\n"; + PMUEventMapJSON[EventName] = eventObj; } } - else - { - PMUEventMap[EventName] = eventObj; - } + } else if (path.find(".tsv") != std::string::npos) { + if (!parse_tsv(path)) + return false; + } else { + cerr << "ERROR: Could not determine Event file type (JSON/TSV)\n"; + return false; } } } @@ -257,7 +315,7 @@ bool initPMUEventMap() return false; } } - if (PMUEventMap.empty()) + if (PMUEventMapJSON.empty() && PMUEventMapsTSV.empty()) { return false; } @@ -265,6 +323,84 @@ bool initPMUEventMap() return true; } +class EventMap { +public: + static bool isEvent(const std::string &eventStr) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) + return true; + for (const auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) + return true; + } + return false; + } + + static bool isField(const std::string &eventStr, const std::string event) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + const auto unitObj = eventObj[event]; + return unitObj.error() != NO_SUCH_FIELD; + } + + for (auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + const auto &col_names = EventMapTSV["COL_NAMES"]; + const auto event_name_it = std::find(col_names.begin(), col_names.end(), event); + if (event_name_it != col_names.end()) { + const size_t event_name_pos = event_name_it - col_names.begin(); + return event_name_pos < EventMapTSV[eventStr].size(); + } + } + } + + return false; + } + + static std::string getField(const std::string &eventStr, const std::string &event) { + std::string res; + + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + const auto unitObj = eventObj[event]; + return std::string(unitObj.get_c_str()); + } + + for (auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + const auto col_names = EventMapTSV["COL_NAMES"]; + const auto event_name_it = std::find(col_names.begin(), col_names.end(), event); + if (event_name_it != col_names.end()) { + const auto event_name_pos = event_name_it - col_names.begin(); + res = EventMapTSV[eventStr][event_name_pos]; + } + } + } + return res; + } + + static void print_event(const std::string &eventStr) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + for (const auto & keyValue : eventObj) + std::cout << keyValue.key << " : " << keyValue.value << "\n"; + return; + } + + for (auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + const auto &col_names = EventMapTSV["COL_NAMES"]; + const auto event = EventMapTSV[eventStr]; + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + for (size_t i = 0 ; i < col_names.size() ; i++) + std::cout << col_names[i] << " : " << event[i] << "\n"; + return; + } + } + } + + } +}; + bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) { if (initPMUEventMap() == false) @@ -299,7 +435,7 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) return true; } - if (PMUEventMap.find(eventStr) == PMUEventMap.end()) + if (!EventMap::isEvent(eventStr)) { cerr << "ERROR: event " << eventStr << " could not be found in event database. Ignoring the event.\n"; return true; @@ -308,7 +444,6 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) auto mod = EventTokens.begin(); ++mod; - const auto eventObj = PMUEventMap[eventStr]; std::string pmuName; PCM::RawEventConfig config = { {0,0,0,0,0}, "" }; bool fixed = false; @@ -339,15 +474,14 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) {std::string("qpi ll"), std::string("xpi")} }; - const auto unitObj = eventObj["Unit"]; - if (unitObj.error() == NO_SUCH_FIELD) + if (!EventMap::isField(eventStr, "Unit")) { pmuName = "core"; config = initCoreConfig(); } else { - std::string unit{ unitObj.get_c_str() }; + std::string unit = EventMap::getField(eventStr, "Unit"); lowerCase(unit); // std::cout << eventStr << " is uncore event for unit " << unit << "\n"; pmuName = (pmuNameMap.find(unit) == pmuNameMap.end()) ? unit : pmuNameMap[unit]; @@ -358,14 +492,14 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) if (1) { // cerr << "pmuName: " << pmuName << " full event "<< fullEventStr << " \n"; - std::string CounterStr{eventObj["Counter"].get_c_str()}; + std::string CounterStr = EventMap::getField(eventStr, "Counter"); // cout << "Counter: " << CounterStr << "\n"; int fixedCounter = -1; fixed = (pcm_sscanf(CounterStr) >> s_expect("Fixed counter ") >> fixedCounter) ? true : false; bool offcore = false; - if (eventObj["Offcore"].error() != NO_SUCH_FIELD) + if (EventMap::isField(eventStr, "Offcore")) { - const std::string offcoreStr{ eventObj["Offcore"].get_c_str() }; + const std::string offcoreStr = EventMap::getField(eventStr, "Offcore"); offcore = (offcoreStr == "1"); } if (pmuName == "core" && curPMUConfigs[pmuName].programmable.empty() && fixed == false) @@ -410,7 +544,7 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) const std::string fieldNameStr{ registerKeyValue.key.begin(), registerKeyValue.key.end() }; if (fieldNameStr == "MSRIndex") { - std::string fieldValueStr{ eventObj[fieldNameStr].get_c_str() }; + string fieldValueStr = EventMap::getField(eventStr, fieldNameStr); // cout << "MSR field " << fieldNameStr << " value is " << fieldValueStr << " (" << read_number(fieldValueStr.c_str()) << ") offcore=" << offcore << "\n"; lowerCase(fieldValueStr); if (fieldValueStr == "0" || fieldValueStr == "0x00") @@ -430,7 +564,7 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) } // cout << " MSR field " << fieldNameStr << " value is " << MSRIndexStr << " (" << read_number(MSRIndexStr.c_str()) << ") offcore=" << offcore << "\n"; simdjson::dom::object MSRObject = registerKeyValue.value[MSRIndexStr]; - const string msrValueStr{ eventObj["MSRValue"].get_c_str() }; + const string msrValueStr = EventMap::getField(eventStr, "MSRValue"); // update the first event setConfig(myPMUConfigs.empty() ? config : myPMUConfigs.front(), MSRObject, read_number(msrValueStr.c_str()), int64_t(MSRObject["Position"])); // update the current as well for display @@ -442,7 +576,7 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) { continue; // field ignored } - if (eventObj[fieldNameStr].error() == NO_SUCH_FIELD) + if (!EventMap::isField(eventStr, fieldNameStr)) { // cerr << fieldNameStr << " not found\n"; if (fieldDescriptionObj["DefaultValue"].error() == NO_SUCH_FIELD) @@ -459,7 +593,8 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) } else { - std::string fieldValueStr{ eventObj[fieldNameStr].get_c_str() }; + std::string fieldValueStr = EventMap::getField(eventStr, fieldNameStr); + fieldValueStr.erase(std::remove(fieldValueStr.begin(), fieldValueStr.end(), '\"'), fieldValueStr.end()); if (offcore && fieldNameStr == "EventCode") { @@ -579,10 +714,7 @@ bool addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) catch (std::exception& e) { cerr << "Error while setting a register field for event " << fullEventStr << " : " << e.what() << "\n"; - for (const auto & keyValue : eventObj) - { - std::cout << keyValue.key << " : " << keyValue.value << "\n"; - } + EventMap::print_event(eventStr); return false; } } diff --git a/test.sh b/test.sh index 8f773779..3f03ca1b 100644 --- a/test.sh +++ b/test.sh @@ -109,3 +109,96 @@ if [ "$?" != 2 ]; then fi popd + +### Check pcm-raw with event files +# Download nescessary files +if [ ! -f "mapfile.csv" ]; then + echo "Downloading https://download.01.org/perfmon/mapfile.csv" + wget -q --timeout=10 https://download.01.org/perfmon/mapfile.csv + if [ "$?" -ne "0" ]; then + echo "Could not download mapfile.csv" + exit 1 + fi +fi + +VENDOR=$(lscpu | grep "Vendor ID:" | awk '{print $3}') +FAMILY=$(lscpu | grep "CPU family:" | awk '{print $3}') +MODEL=$(lscpu | grep "Model:" | awk '{printf("%x", $2)}') +STRING="${VENDOR}-${FAMILY}-${MODEL}-" +FILES=$(grep $STRING "mapfile.csv" | awk -F "\"*,\"*" '{print $3}') +DIRS= + +for FILE in $FILES +do + DIR="$(dirname $FILE)" + DIR="${DIR#?}" + if [[ ! " ${DIRS[*]} " =~ " ${DIR} " ]]; then + DIRS+="${DIR} " + fi +done + +for DIR in $DIRS +do + if [ ! -d $DIR ]; then + mkdir $DIR + cd $DIR + + DIRPATH="https://download.01.org/perfmon/${DIR}/" + echo "Downloading all files from ${DIRPATH}" + + wget -q --timeout=10 -r -l1 --no-parent -A "*.json" $DIRPATH + if [ "$?" -ne "0" ]; then + cd .. + echo "Could not download $DIR" + exit 1 + fi + wget -q --timeout=10 -r -l1 --no-parent -A "*.tsv" $DIRPATH + mv download.01.org/perfmon/${DIR}/* . + rm -rf download.01.org + cd .. + fi +done + +# Run workaround to avoid 'Performance Monitoring Unit is occupied by other application' +# errors when running pcm-raw.x +PCM_NO_PERF=1 ./pcm.x -r 2> /dev/null > /dev/null -- sleep 0 + +# Now check pcm-raw with JSON files from mapFile.csv +./pcm-raw.x -e LD_BLOCKS.STORE_FORWARD -e CPU_CLK_UNHALTED.THREAD_ANY -e INST_RETIRED.ANY -- sleep 1 +if [ "$?" -ne "0" ]; then + echo "Error in pcm-raw.x" + exit 1 +fi + +# Now get corresponding TSV files and replace JSON files in mapFile.csv with them +cp "mapfile.csv" "mapfile.csv_orig" +for FILE in $FILES +do + DIR="$(dirname $FILE)" + DIR="${DIR#?}" + cd $DIR + BASE="$(basename $FILE)" + TYPE="$(echo $BASE | sed 's/_v[0-9].*json//g')" + # TYPE can be for example: skylakex_core or skylakex_uncore. + CMD="find . -type f -regex '\.\/${TYPE}_v[0-9]*\.[0-9]*.tsv'" + TSVFILE=$(eval $CMD) + TSVFILE="${TSVFILE:2}" + cd .. + CMD="sed -i 's/${BASE}/${TSVFILE}/g' mapfile.csv" + eval $CMD +done + +# Run workaround to avoid 'Performance Monitoring Unit is occupied by other application' +# errors when running pcm-raw.x +PCM_NO_PERF=1 ./pcm.x -r 2> /dev/null > /dev/null -- sleep 0 + +# Check pcm-raw with TSV files +./pcm-raw.x -e LD_BLOCKS.STORE_FORWARD -e CPU_CLK_UNHALTED.THREAD_ANY -e INST_RETIRED.ANY -- sleep 1 +if [ "$?" -ne "0" ]; then + echo "Error in pcm-raw.x" + rm -rf mapfile.csv + cp "mapfile.csv_orig" "mapfile.csv" + exit 1 +fi +rm -rf mapfile.csv +cp "mapfile.csv_orig" "mapfile.csv" From 800c19c96d4c0767f0d2f905550408ed5bc24eb2 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Thu, 16 Dec 2021 04:44:00 -0700 Subject: [PATCH 12/12] robustness enhancements --- cpuasynchcounter.h | 6 +++--- cpucounters.cpp | 14 ++++++++------ mutex.h | 6 +++--- pci.h | 5 +++-- pcm-sensor-server.cpp | 13 ++++++++++++- threadpool.h | 4 +++- topology.h | 1 + 7 files changed, 33 insertions(+), 16 deletions(-) diff --git a/cpuasynchcounter.h b/cpuasynchcounter.h index c294330c..883824e8 100644 --- a/cpuasynchcounter.h +++ b/cpuasynchcounter.h @@ -80,7 +80,7 @@ class AsynchronCounterState { ~AsynchronCounterState() { pthread_cancel(UpdateThread); - pthread_mutex_destroy(&CounterMutex); + if (pthread_mutex_destroy(&CounterMutex) != 0) std::cerr << "pthread_mutex_destroy failed\n"; m->cleanup(); delete[] cstates1; delete[] cstates2; @@ -190,7 +190,7 @@ void * UpdateCounters(void * state) AsynchronCounterState * s = (AsynchronCounterState *)state; while (true) { - pthread_mutex_lock(&(s->CounterMutex)); + if (pthread_mutex_lock(&(s->CounterMutex)) != 0) std::cerr << "pthread_mutex_lock failed\n"; for (uint32 core = 0; core < s->m->getNumCores(); ++core) { s->cstates1[core] = std::move(s->cstates2[core]); s->cstates2[core] = s->m->getCoreCounterState(core); @@ -204,7 +204,7 @@ void * UpdateCounters(void * state) s->sstate1 = std::move(s->sstate2); s->sstate2 = s->m->getSystemCounterState(); - pthread_mutex_unlock(&(s->CounterMutex)); + if (pthread_mutex_unlock(&(s->CounterMutex)) != 0) std::cerr << "pthread_mutex_unlock failed\n"; sleep(1); } return NULL; diff --git a/cpucounters.cpp b/cpucounters.cpp index f6598e9b..10fa724c 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -161,9 +161,9 @@ class InstanceLock public: InstanceLock(const bool global_) : globalSemaphoreName(PCM_INSTANCE_LOCK_SEMAPHORE_NAME), globalSemaphore(NULL), global(global_) { - if(!global) + if (!global) { - pthread_mutex_lock(&processIntanceMutex); + if (pthread_mutex_lock(&processIntanceMutex) != 0) std::cerr << "pthread_mutex_lock failed\n"; return; } umask(0); @@ -195,9 +195,9 @@ class InstanceLock } ~InstanceLock() { - if(!global) + if (!global) { - pthread_mutex_unlock(&processIntanceMutex); + if (pthread_mutex_unlock(&processIntanceMutex) != 0) std::cerr << "pthread_mutex_unlock failed\n"; return; } if (sem_post(globalSemaphore)) { @@ -2107,6 +2107,7 @@ class CoreTaskQueue std::thread worker; CoreTaskQueue() = delete; CoreTaskQueue(CoreTaskQueue &) = delete; + CoreTaskQueue & operator = (CoreTaskQueue &) = delete; public: CoreTaskQueue(int32 core) : worker([=]() { @@ -4612,7 +4613,7 @@ PCM::ErrorCode PCM::program(const RawPMUConfigs& curPMUConfigs_, const bool sile fixedReg.value = 0; for (const auto & cfg : corePMUConfig.fixed) { - fixedReg.value |= cfg.first[0]; + fixedReg.value |= uint64(cfg.first[0]); } conf.fixedCfg = &fixedReg; } @@ -7221,7 +7222,8 @@ void ServerPCICFGUncore::initMemTest(ServerPCICFGUncore::MemTestParam & param) std::cerr << "ERROR: mmap failed\n"; return; } - unsigned long long maxNode = (unsigned long long)(readMaxFromSysFS("/sys/devices/system/node/online") + 1); + const int64 onlineNodes = (int64)readMaxFromSysFS("/sys/devices/system/node/online"); + unsigned long long maxNode = (unsigned long long)(onlineNodes + 1); if (maxNode == 0) { std::cerr << "ERROR: max node is 0 \n"; diff --git a/mutex.h b/mutex.h index 42be9889..af8426c3 100644 --- a/mutex.h +++ b/mutex.h @@ -32,7 +32,7 @@ namespace pcm #ifdef _MSC_VER CloseHandle(mutex_); #else - pthread_mutex_destroy(&mutex_); + if (pthread_mutex_destroy(&mutex_) != 0) std::cerr << "pthread_mutex_destroy failed\n"; #endif } @@ -41,7 +41,7 @@ namespace pcm #ifdef _MSC_VER WaitForSingleObject(mutex_, INFINITE); #else - pthread_mutex_lock(&mutex_); + if (pthread_mutex_lock(&mutex_) != 0) std::cerr << "pthread_mutex_lock failed\n";; #endif } void unlock() @@ -49,7 +49,7 @@ namespace pcm #ifdef _MSC_VER ReleaseMutex(mutex_); #else - pthread_mutex_unlock(&mutex_); + if(pthread_mutex_unlock(&mutex_) != 0) std::cerr << "pthread_mutex_unlock failed\n"; #endif } diff --git a/pci.h b/pci.h index acdd5700..c60e834e 100644 --- a/pci.h +++ b/pci.h @@ -100,8 +100,9 @@ class PciHandleM uint32 function; uint64 base_addr; - PciHandleM(); // forbidden - PciHandleM(PciHandleM &); // forbidden + PciHandleM() = delete; // forbidden + PciHandleM(PciHandleM &) = delete; // forbidden + PciHandleM & operator = (PciHandleM &) = delete; // forbidden public: PciHandleM(uint32 bus_, uint32 device_, uint32 function_); diff --git a/pcm-sensor-server.cpp b/pcm-sensor-server.cpp index eae34f6a..d1e9ae91 100644 --- a/pcm-sensor-server.cpp +++ b/pcm-sensor-server.cpp @@ -83,6 +83,7 @@ class Indent { } Indent() = delete; Indent(Indent const &) = default; + Indent & operator = (Indent const &) = default; ~Indent() = default; friend std::stringstream& operator <<( std::stringstream& stream, Indent in ); @@ -130,6 +131,7 @@ class datetime { datetime( std::tm t ) : now( t ) {} ~datetime() = default; datetime( datetime const& ) = default; + datetime & operator = ( datetime const& ) = default; public: void printDateTimeString( std::ostream& os ) const { @@ -171,6 +173,7 @@ class date { } ~date() = default; date( date const& ) = default; + date & operator = ( date const& ) = default; public: void printDate( std::ostream& os ) const { @@ -287,6 +290,7 @@ class JSONPrinter : Visitor } JSONPrinter( JSONPrinter const & ) = delete; + JSONPrinter & operator = ( JSONPrinter const & ) = delete; JSONPrinter() = delete; CoreCounterState const getCoreCounter( std::shared_ptr ag, uint32 tid ) const { @@ -546,6 +550,7 @@ class PrometheusPrinter : Visitor } PrometheusPrinter( PrometheusPrinter const & ) = delete; + PrometheusPrinter & operator = ( PrometheusPrinter const & ) = delete; PrometheusPrinter() = delete; CoreCounterState const getCoreCounter( std::shared_ptr ag, uint32 tid ) const { @@ -1062,7 +1067,8 @@ class basic_socketstream : public std::basic_iostream { } void close() { - ::close( socketBuffer_.socket() ); + const auto s = socketBuffer_.socket(); + if (s != -1) ::close(s); socketBuffer_.setSocket( 0 ); } @@ -1085,6 +1091,7 @@ class Server { shi->installHandler( SignalHandler::handleSignal, SIGINT ); } Server( Server const & ) = delete; + Server & operator = ( Server const & ) = delete; virtual ~Server() = default; public: @@ -1972,6 +1979,7 @@ class HTTPMessage { protected: HTTPMessage() = default; HTTPMessage( HTTPMessage const & ) = default; + HTTPMessage & operator = ( HTTPMessage const & ) = default; ~HTTPMessage() = default; public: @@ -2103,6 +2111,7 @@ class HTTPRequest : public HTTPMessage { public: HTTPRequest() : method_( HTTPRequestMethod::GET ) {} HTTPRequest( HTTPRequest const & ) = default; + HTTPRequest & operator = ( HTTPRequest const & ) = default; ~HTTPRequest() = default; template @@ -2136,6 +2145,7 @@ class HTTPResponse : public HTTPMessage { public: HTTPResponse() : responseCode_( HTTPResponseCode::RC_200_OK ) {} HTTPResponse( HTTPResponse const & ) = default; + HTTPResponse & operator = ( HTTPResponse const & ) = default; virtual ~HTTPResponse() = default; template @@ -2593,6 +2603,7 @@ class HTTPServer : public Server { } HTTPServer( HTTPServer const & ) = delete; + HTTPServer & operator = ( HTTPServer const & ) = delete; virtual ~HTTPServer() { pcf_->stop(); diff --git a/threadpool.h b/threadpool.h index c460b880..4cf8398a 100644 --- a/threadpool.h +++ b/threadpool.h @@ -81,6 +81,7 @@ class ThreadPool { } ThreadPool( ThreadPool const& ) = delete; + ThreadPool & operator = ( ThreadPool const& ) = delete; public: ~ThreadPool() { @@ -136,6 +137,7 @@ class WorkQueue { public: WorkQueue() : tp_( ThreadPool::getInstance() ), workProcessed_(0) {} WorkQueue( WorkQueue const& ) = delete; + WorkQueue & operator = ( WorkQueue const& ) = delete; ~WorkQueue() = default; // Just forwarding to the threadpool @@ -149,4 +151,4 @@ class WorkQueue { size_t workProcessed_; }; -} // namespace pcm \ No newline at end of file +} // namespace pcm diff --git a/topology.h b/topology.h index 46d49c0f..485cd955 100644 --- a/topology.h +++ b/topology.h @@ -380,6 +380,7 @@ class SystemRoot : public SystemObject { SystemRoot(PCM * p) : pcm_(p) {} SystemRoot( SystemRoot const & ) = delete; // do not try to copy this please + SystemRoot & operator = ( SystemRoot const & ) = delete; // do not try to copy this please virtual ~SystemRoot() { pcm_ = nullptr;