diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index aa1b6fc9..68abab4b 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #ifdef __APPLE__ #include @@ -3834,30 +3835,54 @@ PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter return PCM::Success; } +void PCM::checkStatus(const PCM::ErrorCode status) +{ + switch (status) + { + case pcm::PCM::Success: + { + break; + } + case pcm::PCM::MSRAccessDenied: + throw std::system_error(pcm::PCM::MSRAccessDenied, std::generic_category(), + "Access to Intel(r) Performance Counter Monitor has denied (no MSR or PCI CFG space access)."); + case pcm::PCM::PMUBusy: + throw std::system_error(pcm::PCM::PMUBusy, std::generic_category(), + "Access to Intel(r) Performance Counter Monitor has denied (Performance Monitoring Unit" + " is occupied by other application). Try to stop the application that uses PMU," + " or reset PMU configuration from PCM application itself"); + default: + throw std::system_error(pcm::PCM::UnknownError, std::generic_category(), + "Access to Intel(r) Performance Counter Monitor has denied (Unknown error)."); + } +} + void PCM::checkError(const PCM::ErrorCode code) { - switch (code) + try { - case PCM::Success: - break; - case PCM::MSRAccessDenied: - std::cerr << "Access to Intel(r) Performance Counter Monitor has denied (no MSR or PCI CFG space access).\n"; - exit(EXIT_FAILURE); - case PCM::PMUBusy: - std::cerr << "Access to Intel(r) Performance Counter Monitor has denied (Performance Monitoring Unit is occupied by other application)\n"; - std::cerr << "Try to stop the application that uses PMU, or reset PMU configuration from PCM application itself\n"; - std::cerr << "You can try to reset PMU configuration now. Try to reset? (y/n)\n"; - char yn; - std::cin >> yn; - if ('y' == yn) - { - resetPMU(); - std::cerr << "PMU configuration has been reset. Try to rerun the program again.\n"; - } - exit(EXIT_FAILURE); - default: - std::cerr << "Access to Intel(r) Performance Counter Monitor has denied (Unknown error).\n"; - exit(EXIT_FAILURE); + checkStatus(code); + } + catch (const std::system_error &e) + { + switch (e.code().value()) + { + case PCM::PMUBusy: + std::cerr << e.what() << "\n" + << "You can try to reset PMU configuration now. Try to reset? (y/n)" << std::endl; + char yn; + std::cin >> yn; + if ('y' == yn) + { + resetPMU(); + std::cerr << "PMU configuration has been reset. Try to rerun the program again." << std::endl; + } + exit(EXIT_FAILURE); + case PCM::MSRAccessDenied: + default: + std::cerr << e.what() << std::endl; + exit(EXIT_FAILURE); + } } } diff --git a/src/cpucounters.h b/src/cpucounters.h index e38190ee..876b2e5f 100644 --- a/src/cpucounters.h +++ b/src/cpucounters.h @@ -1442,6 +1442,12 @@ class PCM_API PCM */ ErrorCode program(const ProgramMode mode_ = DEFAULT_EVENTS, const void * parameter_ = NULL, const bool silent = false, const int pid = -1); // program counters and start counting + /*! \brief checks the error without side effects. + \throw std::system_error generic_category exception with PCM error code. + \param code error code from the 'program' call + */ + void checkStatus(const ErrorCode status); + /*! \brief checks the error and suggests solution and/or exits the process \param code error code from the 'program' call */