diff options
Diffstat (limited to 'contrib/libs/benchmark/src/perf_counters.cc')
-rw-r--r-- | contrib/libs/benchmark/src/perf_counters.cc | 170 |
1 files changed, 0 insertions, 170 deletions
diff --git a/contrib/libs/benchmark/src/perf_counters.cc b/contrib/libs/benchmark/src/perf_counters.cc deleted file mode 100644 index 8a60088ba7..0000000000 --- a/contrib/libs/benchmark/src/perf_counters.cc +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2021 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "perf_counters.h" - -#include <cstring> -#include <memory> -#include <vector> - -#if defined HAVE_LIBPFM -#error #include "perfmon/pfmlib.h" -#error #include "perfmon/pfmlib_perf_event.h" -#endif - -namespace benchmark { -namespace internal { - -constexpr size_t PerfCounterValues::kMaxCounters; - -#if defined HAVE_LIBPFM -const bool PerfCounters::kSupported = true; - -bool PerfCounters::Initialize() { return pfm_initialize() == PFM_SUCCESS; } - -PerfCounters PerfCounters::Create( - const std::vector<std::string>& counter_names) { - if (counter_names.empty()) { - return NoCounters(); - } - if (counter_names.size() > PerfCounterValues::kMaxCounters) { - GetErrorLogInstance() - << counter_names.size() - << " counters were requested. The minimum is 1, the maximum is " - << PerfCounterValues::kMaxCounters << "\n"; - return NoCounters(); - } - std::vector<int> counter_ids(counter_names.size()); - - const int mode = PFM_PLM3; // user mode only - for (size_t i = 0; i < counter_names.size(); ++i) { - const bool is_first = i == 0; - struct perf_event_attr attr {}; - attr.size = sizeof(attr); - const int group_id = !is_first ? counter_ids[0] : -1; - const auto& name = counter_names[i]; - if (name.empty()) { - GetErrorLogInstance() << "A counter name was the empty string\n"; - return NoCounters(); - } - pfm_perf_encode_arg_t arg{}; - arg.attr = &attr; - - const int pfm_get = - pfm_get_os_event_encoding(name.c_str(), mode, PFM_OS_PERF_EVENT, &arg); - if (pfm_get != PFM_SUCCESS) { - GetErrorLogInstance() << "Unknown counter name: " << name << "\n"; - return NoCounters(); - } - attr.disabled = is_first; - // Note: the man page for perf_event_create suggests inerit = true and - // read_format = PERF_FORMAT_GROUP don't work together, but that's not the - // case. - attr.inherit = true; - attr.pinned = is_first; - attr.exclude_kernel = true; - attr.exclude_user = false; - attr.exclude_hv = true; - // Read all counters in one read. - attr.read_format = PERF_FORMAT_GROUP; - - int id = -1; - static constexpr size_t kNrOfSyscallRetries = 5; - // Retry syscall as it was interrupted often (b/64774091). - for (size_t num_retries = 0; num_retries < kNrOfSyscallRetries; - ++num_retries) { - id = perf_event_open(&attr, 0, -1, group_id, 0); - if (id >= 0 || errno != EINTR) { - break; - } - } - if (id < 0) { - GetErrorLogInstance() - << "Failed to get a file descriptor for " << name << "\n"; - return NoCounters(); - } - - counter_ids[i] = id; - } - if (ioctl(counter_ids[0], PERF_EVENT_IOC_ENABLE) != 0) { - GetErrorLogInstance() << "Failed to start counters\n"; - return NoCounters(); - } - - return PerfCounters(counter_names, std::move(counter_ids)); -} - -void PerfCounters::CloseCounters() const { - if (counter_ids_.empty()) { - return; - } - ioctl(counter_ids_[0], PERF_EVENT_IOC_DISABLE); - for (int fd : counter_ids_) { - close(fd); - } -} -#else // defined HAVE_LIBPFM -const bool PerfCounters::kSupported = false; - -bool PerfCounters::Initialize() { return false; } - -PerfCounters PerfCounters::Create( - const std::vector<std::string>& counter_names) { - if (!counter_names.empty()) { - GetErrorLogInstance() << "Performance counters not supported."; - } - return NoCounters(); -} - -void PerfCounters::CloseCounters() const {} -#endif // defined HAVE_LIBPFM - -Mutex PerfCountersMeasurement::mutex_; -int PerfCountersMeasurement::ref_count_ = 0; -PerfCounters PerfCountersMeasurement::counters_ = PerfCounters::NoCounters(); - -PerfCountersMeasurement::PerfCountersMeasurement( - const std::vector<std::string>& counter_names) - : start_values_(counter_names.size()), end_values_(counter_names.size()) { - MutexLock l(mutex_); - if (ref_count_ == 0) { - counters_ = PerfCounters::Create(counter_names); - } - // We chose to increment it even if `counters_` ends up invalid, - // so that we don't keep trying to create, and also since the dtor - // will decrement regardless of `counters_`'s validity - ++ref_count_; - - BM_CHECK(!counters_.IsValid() || counters_.names() == counter_names); -} - -PerfCountersMeasurement::~PerfCountersMeasurement() { - MutexLock l(mutex_); - --ref_count_; - if (ref_count_ == 0) { - counters_ = PerfCounters::NoCounters(); - } -} - -PerfCounters& PerfCounters::operator=(PerfCounters&& other) noexcept { - if (this != &other) { - CloseCounters(); - - counter_ids_ = std::move(other.counter_ids_); - counter_names_ = std::move(other.counter_names_); - } - return *this; -} -} // namespace internal -} // namespace benchmark |