Ifdef out WarnIfComponentBlockingGuard for benchmark builds

Add USE_BENCHMARK define to benchmark build flags. Guard the
warn_blocking call in finish() with #ifndef USE_BENCHMARK so
scheduler benchmarks using fake monotonic time don't trigger
the underflow (fake now > real millis()).

Remove BenchComponent — no longer needed with the ifdef.
This commit is contained in:
J. Nick Koston
2026-03-17 01:16:34 -10:00
parent e01670eed8
commit 804e2330ec
3 changed files with 8 additions and 15 deletions
+2
View File
@@ -598,9 +598,11 @@ class WarnIfComponentBlockingGuard {
#ifdef USE_RUNTIME_STATS
this->record_runtime_stats_();
#endif
#ifndef USE_BENCHMARK
if (blocking_time > WARN_IF_BLOCKING_OVER_MS) [[unlikely]] {
warn_blocking(this->component_, blocking_time);
}
#endif
return curr_time;
}
+1
View File
@@ -34,6 +34,7 @@ PLATFORMIO_OPTIONS = {
"-O2", # optimize for speed (CodSpeed recommends RelWithDebInfo)
"-g", # debug symbols for profiling
USE_TIME_TIMEZONE_FLAG,
"-DUSE_BENCHMARK", # disable WarnIfComponentBlockingGuard in finish()
],
# Use deep+ LDF mode to ensure PlatformIO detects the benchmark
# library dependency from nested includes.
+5 -15
View File
@@ -10,15 +10,6 @@ namespace esphome::benchmarks {
// sub-microsecond benchmarks.
static constexpr int kInnerIterations = 2000;
// Component subclass that suppresses blocking warnings.
// Under valgrind, 2000 inner iterations take long enough in wall clock
// to trigger WarnIfComponentBlockingGuard. Setting the threshold to max
// prevents log noise without affecting the benchmarked code path.
class BenchComponent : public Component {
public:
BenchComponent() { this->warn_if_blocking_over_ = UINT16_MAX; }
};
// --- Scheduler fast path: no work to do ---
static void Scheduler_Call_NoWork(benchmark::State &state) {
@@ -39,7 +30,7 @@ BENCHMARK(Scheduler_Call_NoWork);
static void Scheduler_Call_TimersNotDue(benchmark::State &state) {
Scheduler scheduler;
BenchComponent dummy_component;
Component dummy_component;
// Add some timeouts far in the future
for (int i = 0; i < 10; i++) {
@@ -63,14 +54,13 @@ BENCHMARK(Scheduler_Call_TimersNotDue);
static void Scheduler_Call_5IntervalsFiring(benchmark::State &state) {
Scheduler scheduler;
BenchComponent dummy_component;
Component dummy_component;
int fire_count = 0;
// Benchmarks the heap-based scheduler dispatch with 5 callbacks firing.
// Uses monotonically increasing fake time so intervals reliably fire every call.
// The first item per call triggers one WarnIfComponentBlockingGuard warning
// (fake now > real millis() causes underflow in finish()), but this is
// consistent overhead per iteration so CodSpeed regression detection works.
// USE_BENCHMARK ifdef in component.h disables WarnIfComponentBlockingGuard
// (fake now > real millis() would cause underflow in finish()).
// interval=0 would cause an infinite loop (reschedules at same now).
for (int i = 0; i < 5; i++) {
scheduler.set_interval(&dummy_component, static_cast<uint32_t>(i), 1, [&fire_count]() { fire_count++; });
@@ -91,7 +81,7 @@ BENCHMARK(Scheduler_Call_5IntervalsFiring);
static void Scheduler_NextScheduleIn(benchmark::State &state) {
Scheduler scheduler;
BenchComponent dummy_component;
Component dummy_component;
// Add some timeouts
for (int i = 0; i < 10; i++) {