Fixes in power benchmarks
- Add support check before running PowerHalAidlBenchmarks for setBoost
and setMode, to avoid testing unsupported values and getting the HAL
in a bad state.
- Introduce loop breaks when a binder call fails, since SkipWithError
is not enough to end the loop early and might cause test timeout if
we try to interact with a HAL in a bad state.
- Move PauseTiming/ResumeTimings to wrap one-way call delays only, as
this API is expensive and should be used sparsely (and it's needed
there to avoid filling up the one-way binder queue).
- Make sure we close all sessions in createHintSession tests.
- Use ndk::enum_range in AIDL enums to cover all available boost and
mode values.
Fix: 351008375
Flag: EXEMPT test only
Change-Id: I6b277d60767f5928e397765b7dcabd709c4f8953
Test: libpowermanager_benchmarks
diff --git a/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp
index 61ab47a..3a1b426 100644
--- a/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp
+++ b/services/powermanager/benchmarks/PowerHalAidlBenchmarks.cpp
@@ -40,10 +40,10 @@
using namespace std::chrono_literals;
// Values from Boost.aidl and Mode.aidl.
-static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(Boost::INTERACTION);
-static constexpr int64_t LAST_BOOST = static_cast<int64_t>(Boost::CAMERA_SHOT);
-static constexpr int64_t FIRST_MODE = static_cast<int64_t>(Mode::DOUBLE_TAP_TO_WAKE);
-static constexpr int64_t LAST_MODE = static_cast<int64_t>(Mode::CAMERA_STREAMING_HIGH);
+static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(*ndk::enum_range<Boost>().begin());
+static constexpr int64_t LAST_BOOST = static_cast<int64_t>(*(ndk::enum_range<Boost>().end()-1));
+static constexpr int64_t FIRST_MODE = static_cast<int64_t>(*ndk::enum_range<Mode>().begin());
+static constexpr int64_t LAST_MODE = static_cast<int64_t>(*(ndk::enum_range<Mode>().end()-1));
class DurationWrapper : public WorkDuration {
public:
@@ -81,14 +81,17 @@
return;
}
- while (state.KeepRunning()) {
+ for (auto _ : state) {
ret = (*hal.*fn)(std::forward<Args1>(args1)...);
- state.PauseTiming();
- if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str());
- if (delay > 0us) {
- testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count());
+ if (!ret.isOk()) {
+ state.SkipWithError(ret.getDescription().c_str());
+ break;
}
- state.ResumeTiming();
+ if (delay > 0us) {
+ state.PauseTiming();
+ testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count());
+ state.ResumeTiming();
+ }
}
}
@@ -123,14 +126,15 @@
return;
}
- while (state.KeepRunning()) {
+ for (auto _ : state) {
ret = (*session.*fn)(std::forward<Args1>(args1)...);
- state.PauseTiming();
- if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str());
- if (ONEWAY_API_DELAY > 0us) {
- testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY)
- .count());
+ if (!ret.isOk()) {
+ state.SkipWithError(ret.getDescription().c_str());
+ break;
}
+ state.PauseTiming();
+ testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY)
+ .count());
state.ResumeTiming();
}
session->close();
@@ -150,11 +154,41 @@
static void BM_PowerHalAidlBenchmarks_setBoost(benchmark::State& state) {
Boost boost = static_cast<Boost>(state.range(0));
+ bool isSupported;
+ std::shared_ptr<IPower> hal = PowerHalLoader::loadAidl();
+
+ if (hal == nullptr) {
+ ALOGV("Power HAL not available, skipping test...");
+ state.SkipWithMessage("Power HAL unavailable");
+ return;
+ }
+
+ ndk::ScopedAStatus ret = hal->isBoostSupported(boost, &isSupported);
+ if (!ret.isOk() || !isSupported) {
+ state.SkipWithMessage("operation unsupported");
+ return;
+ }
+
runBenchmark(state, ONEWAY_API_DELAY, &IPower::setBoost, boost, 1);
}
static void BM_PowerHalAidlBenchmarks_setMode(benchmark::State& state) {
Mode mode = static_cast<Mode>(state.range(0));
+ bool isSupported;
+ std::shared_ptr<IPower> hal = PowerHalLoader::loadAidl();
+
+ if (hal == nullptr) {
+ ALOGV("Power HAL not available, skipping test...");
+ state.SkipWithMessage("Power HAL unavailable");
+ return;
+ }
+
+ ndk::ScopedAStatus ret = hal->isModeSupported(mode, &isSupported);
+ if (!ret.isOk() || !isSupported) {
+ state.SkipWithMessage("operation unsupported");
+ return;
+ }
+
runBenchmark(state, ONEWAY_API_DELAY, &IPower::setMode, mode, false);
}
@@ -178,12 +212,20 @@
ALOGV("Power HAL does not support this operation, skipping test...");
state.SkipWithMessage("operation unsupported");
return;
+ } else if (!ret.isOk()) {
+ state.SkipWithError(ret.getDescription().c_str());
+ return;
+ } else {
+ appSession->close();
}
- while (state.KeepRunning()) {
+ for (auto _ : state) {
ret = hal->createHintSession(tgid, uid, threadIds, durationNanos, &appSession);
+ if (!ret.isOk()) {
+ state.SkipWithError(ret.getDescription().c_str());
+ break;
+ }
state.PauseTiming();
- if (!ret.isOk()) state.SkipWithError(ret.getDescription().c_str());
appSession->close();
state.ResumeTiming();
}
diff --git a/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp
index effddda..0fda686 100644
--- a/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp
+++ b/services/powermanager/benchmarks/PowerHalControllerBenchmarks.cpp
@@ -19,9 +19,9 @@
#include <aidl/android/hardware/power/Boost.h>
#include <aidl/android/hardware/power/Mode.h>
#include <benchmark/benchmark.h>
+#include <chrono>
#include <powermanager/PowerHalController.h>
#include <testUtil.h>
-#include <chrono>
using aidl::android::hardware::power::Boost;
using aidl::android::hardware::power::Mode;
@@ -32,10 +32,10 @@
using namespace std::chrono_literals;
// Values from Boost.aidl and Mode.aidl.
-static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(Boost::INTERACTION);
-static constexpr int64_t LAST_BOOST = static_cast<int64_t>(Boost::CAMERA_SHOT);
-static constexpr int64_t FIRST_MODE = static_cast<int64_t>(Mode::DOUBLE_TAP_TO_WAKE);
-static constexpr int64_t LAST_MODE = static_cast<int64_t>(Mode::CAMERA_STREAMING_HIGH);
+static constexpr int64_t FIRST_BOOST = static_cast<int64_t>(*ndk::enum_range<Boost>().begin());
+static constexpr int64_t LAST_BOOST = static_cast<int64_t>(*(ndk::enum_range<Boost>().end()-1));
+static constexpr int64_t FIRST_MODE = static_cast<int64_t>(*ndk::enum_range<Mode>().begin());
+static constexpr int64_t LAST_MODE = static_cast<int64_t>(*(ndk::enum_range<Mode>().end()-1));
// Delay between oneway method calls to avoid overflowing the binder buffers.
static constexpr std::chrono::microseconds ONEWAY_API_DELAY = 100us;
@@ -43,11 +43,27 @@
template <typename T, class... Args0, class... Args1>
static void runBenchmark(benchmark::State& state, HalResult<T> (PowerHalController::*fn)(Args0...),
Args1&&... args1) {
- while (state.KeepRunning()) {
- PowerHalController controller;
+ PowerHalController initController;
+ HalResult<T> result = (initController.*fn)(std::forward<Args1>(args1)...);
+ if (result.isFailed()) {
+ state.SkipWithError(result.errorMessage());
+ return;
+ } else if (result.isUnsupported()) {
+ ALOGV("Power HAL does not support this operation, skipping test...");
+ state.SkipWithMessage("operation unsupported");
+ return;
+ }
+
+ for (auto _ : state) {
+ PowerHalController controller; // new controller to avoid caching
HalResult<T> ret = (controller.*fn)(std::forward<Args1>(args1)...);
+ if (ret.isFailed()) {
+ state.SkipWithError(ret.errorMessage());
+ break;
+ }
state.PauseTiming();
- if (ret.isFailed()) state.SkipWithError("Power HAL request failed");
+ testDelaySpin(
+ std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY).count());
state.ResumeTiming();
}
}
@@ -57,22 +73,27 @@
HalResult<T> (PowerHalController::*fn)(Args0...), Args1&&... args1) {
PowerHalController controller;
// First call out of test, to cache HAL service and isSupported result.
- (controller.*fn)(std::forward<Args1>(args1)...);
+ HalResult<T> result = (controller.*fn)(std::forward<Args1>(args1)...);
+ if (result.isFailed()) {
+ state.SkipWithError(result.errorMessage());
+ return;
+ } else if (result.isUnsupported()) {
+ ALOGV("Power HAL does not support this operation, skipping test...");
+ state.SkipWithMessage("operation unsupported");
+ return;
+ }
- while (state.KeepRunning()) {
+ for (auto _ : state) {
HalResult<T> ret = (controller.*fn)(std::forward<Args1>(args1)...);
- state.PauseTiming();
if (ret.isFailed()) {
- state.SkipWithError("Power HAL request failed");
+ state.SkipWithError(ret.errorMessage());
+ break;
}
- testDelaySpin(
- std::chrono::duration_cast<std::chrono::duration<float>>(ONEWAY_API_DELAY).count());
- state.ResumeTiming();
}
}
static void BM_PowerHalControllerBenchmarks_init(benchmark::State& state) {
- while (state.KeepRunning()) {
+ for (auto _ : state) {
PowerHalController controller;
controller.init();
}
@@ -90,12 +111,12 @@
static void BM_PowerHalControllerBenchmarks_setBoost(benchmark::State& state) {
Boost boost = static_cast<Boost>(state.range(0));
- runBenchmark(state, &PowerHalController::setBoost, boost, 0);
+ runBenchmark(state, &PowerHalController::setBoost, boost, 1);
}
static void BM_PowerHalControllerBenchmarks_setBoostCached(benchmark::State& state) {
Boost boost = static_cast<Boost>(state.range(0));
- runCachedBenchmark(state, &PowerHalController::setBoost, boost, 0);
+ runCachedBenchmark(state, &PowerHalController::setBoost, boost, 1);
}
static void BM_PowerHalControllerBenchmarks_setMode(benchmark::State& state) {
diff --git a/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp b/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp
index bcb376b..95fd0c2 100644
--- a/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp
+++ b/services/powermanager/benchmarks/PowerHalHidlBenchmarks.cpp
@@ -54,14 +54,17 @@
return;
}
- while (state.KeepRunning()) {
+ for (auto _ : state) {
Return<R> ret = (*hal.*fn)(std::forward<Args1>(args1)...);
- state.PauseTiming();
- if (!ret.isOk()) state.SkipWithError(ret.description().c_str());
- if (delay > 0us) {
- testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count());
+ if (!ret.isOk()) {
+ state.SkipWithError(ret.description().c_str());
+ break;
}
- state.ResumeTiming();
+ if (delay > 0us) {
+ state.PauseTiming();
+ testDelaySpin(std::chrono::duration_cast<std::chrono::duration<float>>(delay).count());
+ state.ResumeTiming();
+ }
}
}