diff --git a/docs/user_guide.md b/docs/user_guide.md index 3fed9261d..ff7d88647 100644 --- a/docs/user_guide.md +++ b/docs/user_guide.md @@ -1604,6 +1604,15 @@ If set, the `ProfilerManager::AfterSetupStart` and end of a separate benchmark run to allow user code to collect and report user-provided profile metrics. +Each method has two overloads: a parameterless one and one taking a +`const benchmark::State&`, which gives access to run information such as the +benchmark name (e.g. for registering named profiling regions). Override +whichever variant you need; the `State`-taking overloads forward to the +parameterless ones by default. When overriding only one overload of a pair, +add a `using benchmark::ProfilerManager::AfterSetupStart;` (respectively +`BeforeTeardownStop`) declaration to your class to avoid hiding the other +overload. + Output collected from this profiling run must be reported separately. diff --git a/include/benchmark/managers.h b/include/benchmark/managers.h index e8b6cd474..e3444d525 100644 --- a/include/benchmark/managers.h +++ b/include/benchmark/managers.h @@ -24,6 +24,8 @@ namespace benchmark { +class State; + class MemoryManager { public: static constexpr int64_t TombstoneValue = std::numeric_limits::max(); @@ -54,8 +56,20 @@ void RegisterMemoryManager(MemoryManager* memory_manager); class ProfilerManager { public: virtual ~ProfilerManager() {} - virtual void AfterSetupStart() = 0; - virtual void BeforeTeardownStop() = 0; + // Kept for backwards compatibility; new code should override the + // State-taking overloads below. Note that a subclass overriding only one + // overload of a pair hides the other; add + // `using benchmark::ProfilerManager::AfterSetupStart;` (respectively + // `BeforeTeardownStop`) to silence -Woverloaded-virtual. + virtual void AfterSetupStart() {} + virtual void BeforeTeardownStop() {} + // Called with the State of the benchmark run being profiled, giving + // access to e.g. the benchmark name. The default implementations forward + // to the parameterless hooks above. + virtual void AfterSetupStart(const State& /*state*/) { AfterSetupStart(); } + virtual void BeforeTeardownStop(const State& /*state*/) { + BeforeTeardownStop(); + } }; BENCHMARK_EXPORT diff --git a/src/benchmark.cc b/src/benchmark.cc index 7217fc4ed..b6173d18b 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -331,7 +331,7 @@ void State::StartKeepRunning() { started_ = true; total_iterations_ = skipped() ? 0 : max_iterations; if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) { - profiler_manager_->AfterSetupStart(); + profiler_manager_->AfterSetupStart(*this); } manager_->StartStopBarrier(); if (!skipped()) { @@ -349,7 +349,7 @@ void State::FinishKeepRunning() { finished_ = true; manager_->StartStopBarrier(); if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) { - profiler_manager_->BeforeTeardownStop(); + profiler_manager_->BeforeTeardownStop(*this); } } diff --git a/test/profiler_manager_gtest.cc b/test/profiler_manager_gtest.cc index 6e83e32a9..ab4adefb5 100644 --- a/test/profiler_manager_gtest.cc +++ b/test/profiler_manager_gtest.cc @@ -10,6 +10,9 @@ namespace { class TestProfilerManager : public benchmark::ProfilerManager { public: + using benchmark::ProfilerManager::AfterSetupStart; + using benchmark::ProfilerManager::BeforeTeardownStop; + void AfterSetupStart() override { ++start_called; } void BeforeTeardownStop() override { ++stop_called; } diff --git a/test/profiler_manager_iterations_test.cc b/test/profiler_manager_iterations_test.cc index 90b34a1da..dffeb686e 100644 --- a/test/profiler_manager_iterations_test.cc +++ b/test/profiler_manager_iterations_test.cc @@ -17,6 +17,9 @@ int iteration_count = 0; int end_profiler_iteration_count = 0; class TestProfilerManager : public benchmark::ProfilerManager { + using benchmark::ProfilerManager::AfterSetupStart; + using benchmark::ProfilerManager::BeforeTeardownStop; + void AfterSetupStart() override { iteration_count = 0; } void BeforeTeardownStop() override { end_profiler_iteration_count = iteration_count; diff --git a/test/profiler_manager_test.cc b/test/profiler_manager_test.cc index bd86d42c0..f825181c1 100644 --- a/test/profiler_manager_test.cc +++ b/test/profiler_manager_test.cc @@ -2,6 +2,7 @@ #include #include +#include #include "benchmark/benchmark_api.h" #include "benchmark/managers.h" @@ -13,11 +14,21 @@ namespace { class TestProfilerManager : public benchmark::ProfilerManager { public: - void AfterSetupStart() override { ++start_called; } + using benchmark::ProfilerManager::AfterSetupStart; + using benchmark::ProfilerManager::BeforeTeardownStop; + + // New-style hook receiving the State of the benchmark being profiled. + void AfterSetupStart(const benchmark::State& state) override { + ++start_called; + benchmark_name = state.name(); + } + // Old-style hook; must still be reached through the default forwarding of + // BeforeTeardownStop(const State&). void BeforeTeardownStop() override { ++stop_called; } int start_called = 0; int stop_called = 0; + std::string benchmark_name; }; void BM_empty(benchmark::State& state) { @@ -55,4 +66,5 @@ int main(int argc, char* argv[]) { assert(pm->start_called == 1); assert(pm->stop_called == 1); + assert(pm->benchmark_name == "BM_empty"); }