20 #if defined HAVE_LIBPFM
21 #include "perfmon/pfmlib.h"
22 #include "perfmon/pfmlib_perf_event.h"
30 #if defined HAVE_LIBPFM
36 const std::vector<std::string>& counter_names) {
37 if (counter_names.empty()) {
42 << counter_names.size()
43 <<
" counters were requested. The minimum is 1, the maximum is "
47 std::vector<int> counter_ids(counter_names.size());
49 const int mode = PFM_PLM3;
50 for (
size_t i = 0;
i < counter_names.size(); ++
i) {
51 const bool is_first =
i == 0;
52 struct perf_event_attr
attr{};
54 const int group_id = !is_first ? counter_ids[0] : -1;
55 const auto&
name = counter_names[
i];
60 pfm_perf_encode_arg_t
arg{};
64 pfm_get_os_event_encoding(
name.c_str(),
mode, PFM_OS_PERF_EVENT, &
arg);
65 if (pfm_get != PFM_SUCCESS) {
69 attr.disabled = is_first;
74 attr.pinned = is_first;
75 attr.exclude_kernel =
true;
76 attr.exclude_user =
false;
77 attr.exclude_hv =
true;
79 attr.read_format = PERF_FORMAT_GROUP;
82 static constexpr
size_t kNrOfSyscallRetries = 5;
84 for (
size_t num_retries = 0; num_retries < kNrOfSyscallRetries;
86 id = perf_event_open(&
attr, 0, -1, group_id, 0);
87 if (
id >= 0 || errno != EINTR) {
93 <<
"Failed to get a file descriptor for " <<
name <<
"\n";
99 if (ioctl(counter_ids[0], PERF_EVENT_IOC_ENABLE) != 0) {
116 #else // defined HAVE_LIBPFM
122 const std::vector<std::string>& counter_names) {
123 if (!counter_names.empty()) {
130 #endif // defined HAVE_LIBPFM