diff options
| author | 2024-11-12 18:15:58 +0000 | |
|---|---|---|
| committer | 2024-11-12 18:15:58 +0000 | |
| commit | d72e795b7852c19083644d5a4e9a17959a00bed9 (patch) | |
| tree | 8353f0dc627053b11644a92faaa7e7c6e974f401 | |
| parent | 151f69f7069967da811a6ac4ebacc60ae7fa9714 (diff) | |
Revert "Add public ADPF load hints with better rate limiter and ..."
Revert submission 29997970-load_hints
Reason for revert: Droidmonitor created revert due to b/378700893. Will be verifying through ABTD before submission.
Reverted changes: /q/submissionid:29997970-load_hints
Change-Id: I6feaa338a352ce58ef34594598a3ac3b5d7a961d
| -rw-r--r-- | core/java/android/os/flags.aconfig | 8 | ||||
| -rw-r--r-- | native/android/libandroid.map.txt | 4 | ||||
| -rw-r--r-- | native/android/performance_hint.cpp | 199 | ||||
| -rw-r--r-- | native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 29 |
4 files changed, 44 insertions, 196 deletions
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig index b2c755d7e2f6..9c83bc2c88ec 100644 --- a/core/java/android/os/flags.aconfig +++ b/core/java/android/os/flags.aconfig @@ -66,14 +66,6 @@ flag { } flag { - name: "adpf_use_load_hints" - namespace: "game" - description: "Guards use of the ADPF public load hints behind a readonly flag" - is_fixed_read_only: true - bug: "367803904" -} - -flag { name: "allow_consentless_bugreport_delegated_consent" namespace: "crumpet" description: "Allow privileged apps to call bugreport generation without enforcing user consent and delegate it to the calling app instead" diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e976138e52d6..b025cb880ee7 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -352,8 +352,6 @@ LIBANDROID { APerformanceHint_setThreads; # introduced=UpsideDownCake APerformanceHint_setPreferPowerEfficiency; # introduced=VanillaIceCream APerformanceHint_reportActualWorkDuration2; # introduced=VanillaIceCream - APerformanceHint_notifyWorkloadIncrease; # introduced=36 - APerformanceHint_notifyWorkloadReset; # introduced=36 AWorkDuration_create; # introduced=VanillaIceCream AWorkDuration_release; # introduced=VanillaIceCream AWorkDuration_setWorkPeriodStartTimestampNanos; # introduced=VanillaIceCream @@ -372,8 +370,6 @@ LIBANDROID_PLATFORM { APerformanceHint_getThreadIds; APerformanceHint_createSessionInternal; APerformanceHint_setUseFMQForTesting; - APerformanceHint_getRateLimiterPropertiesForTesting; - APerformanceHint_setUseNewLoadHintBehaviorForTesting; extern "C++" { ASurfaceControl_registerSurfaceStatsListener*; ASurfaceControl_unregisterSurfaceStatsListener*; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index e2fa94dd39bb..15f77cebf3ba 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -33,14 +33,12 @@ #include <android/performance_hint.h> #include <android/trace.h> #include <android_os.h> -#include <cutils/trace.h> #include <fmq/AidlMessageQueue.h> #include <inttypes.h> #include <performance_hint_private.h> #include <utils/SystemClock.h> #include <chrono> -#include <format> #include <future> #include <set> #include <utility> @@ -65,22 +63,6 @@ struct APerformanceHintSession; constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count(); struct AWorkDuration : public hal::WorkDuration {}; -// A pair of values that determine the behavior of the -// load hint rate limiter, to only allow "X hints every Y seconds" -constexpr double kLoadHintInterval = std::chrono::nanoseconds(2s).count(); -constexpr double kMaxLoadHintsPerInterval = 20; -constexpr double kReplenishRate = kMaxLoadHintsPerInterval / kLoadHintInterval; -bool kForceNewHintBehavior = false; - -template <class T> -constexpr int32_t enum_size() { - return static_cast<int32_t>(*(ndk::enum_range<T>().end() - 1)) + 1; -} - -bool useNewLoadHintBehavior() { - return android::os::adpf_use_load_hints() || kForceNewHintBehavior; -} - // Shared lock for the whole PerformanceHintManager and sessions static std::mutex sHintMutex = std::mutex{}; class FMQWrapper { @@ -94,8 +76,7 @@ public: hal::WorkDuration* durations, size_t count) REQUIRES(sHintMutex); bool updateTargetWorkDuration(std::optional<hal::SessionConfig>& config, int64_t targetDurationNanos) REQUIRES(sHintMutex); - bool sendHints(std::optional<hal::SessionConfig>& config, std::vector<hal::SessionHint>& hint, - int64_t now) REQUIRES(sHintMutex); + bool sendHint(std::optional<hal::SessionConfig>& config, SessionHint hint) REQUIRES(sHintMutex); bool setMode(std::optional<hal::SessionConfig>& config, hal::SessionMode, bool enabled) REQUIRES(sHintMutex); void setToken(ndk::SpAIBinder& token); @@ -105,11 +86,10 @@ public: private: template <HalChannelMessageContents::Tag T, bool urgent = false, class C = HalChannelMessageContents::_at<T>> - bool sendMessages(std::optional<hal::SessionConfig>& config, C* message, size_t count = 1, - int64_t now = ::android::uptimeNanos()) REQUIRES(sHintMutex); - template <HalChannelMessageContents::Tag T, class C = HalChannelMessageContents::_at<T>> - void writeBuffer(C* message, hal::SessionConfig& config, size_t count, int64_t now) + bool sendMessages(std::optional<hal::SessionConfig>& config, C* message, size_t count = 1) REQUIRES(sHintMutex); + template <HalChannelMessageContents::Tag T, class C = HalChannelMessageContents::_at<T>> + void writeBuffer(C* message, hal::SessionConfig& config, size_t count) REQUIRES(sHintMutex); bool isActiveLocked() REQUIRES(sHintMutex); bool updatePersistentTransaction() REQUIRES(sHintMutex); @@ -140,7 +120,6 @@ public: hal::SessionTag tag = hal::SessionTag::APP); int64_t getPreferredRateNanos() const; FMQWrapper& getFMQWrapper(); - bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex); private: // Necessary to create an empty binder object @@ -159,8 +138,6 @@ private: ndk::SpAIBinder mToken; const int64_t mPreferredRateNanos; FMQWrapper mFMQWrapper; - double mHintBudget = kMaxLoadHintsPerInterval; - int64_t mLastBudgetReplenish = 0; }; struct APerformanceHintSession { @@ -174,9 +151,7 @@ public: int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); - int sendHints(std::vector<hal::SessionHint>& hints, int64_t now, const char* debugName); - int notifyWorkloadIncrease(bool cpu, bool gpu, const char* debugName); - int notifyWorkloadReset(bool cpu, bool gpu, const char* debugName); + int sendHint(SessionHint hint); int setThreads(const int32_t* threadIds, size_t size); int getThreadIds(int32_t* const threadIds, size_t* size); int setPreferPowerEfficiency(bool enabled); @@ -198,8 +173,6 @@ private: // Last target hit timestamp int64_t mLastTargetMetTimestamp GUARDED_BY(sHintMutex); // Last hint reported from sendHint indexed by hint value - // This is only used by the old rate limiter impl and is replaced - // with the new rate limiter under a flag std::vector<int64_t> mLastHintSentTimestamp GUARDED_BY(sHintMutex); // Cached samples std::vector<hal::WorkDuration> mActualWorkDurations GUARDED_BY(sHintMutex); @@ -282,21 +255,6 @@ APerformanceHintManager* APerformanceHintManager::create(std::shared_ptr<IHintMa return new APerformanceHintManager(manager, preferredRateNanos); } -bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) { - mHintBudget = - std::max(kMaxLoadHintsPerInterval, - mHintBudget + - static_cast<double>(now - mLastBudgetReplenish) * kReplenishRate); - mLastBudgetReplenish = now; - - // If this youngest timestamp isn't older than the timeout time, we can't send - if (hints.size() > mHintBudget) { - return false; - } - mHintBudget -= hints.size(); - return true; -} - APerformanceHintSession* APerformanceHintManager::createSession( const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos, hal::SessionTag tag) { @@ -334,7 +292,9 @@ FMQWrapper& APerformanceHintManager::getFMQWrapper() { // ===================================== APerformanceHintSession implementation -constexpr int kNumEnums = enum_size<hal::SessionHint>(); +constexpr int kNumEnums = + ndk::enum_range<hal::SessionHint>().end() - ndk::enum_range<hal::SessionHint>().begin(); + APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager, std::shared_ptr<IHintSession> session, int64_t preferredRateNanos, @@ -401,83 +361,31 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration)); } -int APerformanceHintSession::sendHints(std::vector<hal::SessionHint>& hints, int64_t now, - const char*) { +int APerformanceHintSession::sendHint(SessionHint hint) { std::scoped_lock lock(sHintMutex); - if (hints.empty()) { + if (hint < 0 || hint >= static_cast<int32_t>(mLastHintSentTimestamp.size())) { + ALOGE("%s: invalid session hint %d", __FUNCTION__, hint); return EINVAL; } - for (auto&& hint : hints) { - if (static_cast<int32_t>(hint) < 0 || static_cast<int32_t>(hint) >= kNumEnums) { - ALOGE("%s: invalid session hint %d", __FUNCTION__, hint); - return EINVAL; - } - } + int64_t now = uptimeNanos(); - if (useNewLoadHintBehavior()) { - if (!APerformanceHintManager::getInstance()->canSendLoadHints(hints, now)) { - return EBUSY; - } - } - // keep old rate limiter behavior for legacy flag - else { - for (auto&& hint : hints) { - if (now < (mLastHintSentTimestamp[static_cast<int32_t>(hint)] + SEND_HINT_TIMEOUT)) { - return EBUSY; - } - } + // Limit sendHint to a pre-detemined rate for safety + if (now < (mLastHintSentTimestamp[hint] + SEND_HINT_TIMEOUT)) { + return 0; } - if (!getFMQ().sendHints(mSessionConfig, hints, now)) { - for (auto&& hint : hints) { - ndk::ScopedAStatus ret = mHintSession->sendHint(static_cast<int32_t>(hint)); + if (!getFMQ().sendHint(mSessionConfig, hint)) { + ndk::ScopedAStatus ret = mHintSession->sendHint(hint); - if (!ret.isOk()) { - ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.getMessage()); - return EPIPE; - } - } - } - - if (!useNewLoadHintBehavior()) { - for (auto&& hint : hints) { - mLastHintSentTimestamp[static_cast<int32_t>(hint)] = now; + if (!ret.isOk()) { + ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.getMessage()); + return EPIPE; } } - - if (ATrace_isEnabled()) { - ATRACE_INSTANT("Sending load hint"); - } - + mLastHintSentTimestamp[hint] = now; return 0; } -int APerformanceHintSession::notifyWorkloadIncrease(bool cpu, bool gpu, const char* debugName) { - std::vector<hal::SessionHint> hints(2); - hints.clear(); - if (cpu) { - hints.push_back(hal::SessionHint::CPU_LOAD_UP); - } - if (gpu) { - hints.push_back(hal::SessionHint::GPU_LOAD_UP); - } - int64_t now = ::android::uptimeNanos(); - return sendHints(hints, now, debugName); -} - -int APerformanceHintSession::notifyWorkloadReset(bool cpu, bool gpu, const char* debugName) { - std::vector<hal::SessionHint> hints(2); - hints.clear(); - if (cpu) { - hints.push_back(hal::SessionHint::CPU_LOAD_RESET); - } - if (gpu) { - hints.push_back(hal::SessionHint::GPU_LOAD_RESET); - } - int64_t now = ::android::uptimeNanos(); - return sendHints(hints, now, debugName); -} - int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) { if (size == 0) { ALOGE("%s: the list of thread ids must not be empty.", __FUNCTION__); @@ -657,25 +565,24 @@ void FMQWrapper::stopChannel(IHintManager* manager) { } template <HalChannelMessageContents::Tag T, class C> -void FMQWrapper::writeBuffer(C* message, hal::SessionConfig& config, size_t count, int64_t now) { - for (size_t i = 0; i < count; ++i) { - new (mFmqTransaction.getSlot(i)) hal::ChannelMessage{ - .sessionID = static_cast<int32_t>(config.id), - .timeStampNanos = now, - .data = HalChannelMessageContents::make<T, C>(std::move(*(message + i))), - }; - } +void FMQWrapper::writeBuffer(C* message, hal::SessionConfig& config, size_t) { + new (mFmqTransaction.getSlot(0)) hal::ChannelMessage{ + .sessionID = static_cast<int32_t>(config.id), + .timeStampNanos = ::android::uptimeNanos(), + .data = HalChannelMessageContents::make<T, C>(std::move(*message)), + }; } template <> void FMQWrapper::writeBuffer<HalChannelMessageContents::workDuration>(hal::WorkDuration* messages, hal::SessionConfig& config, - size_t count, int64_t now) { + size_t count) { for (size_t i = 0; i < count; ++i) { hal::WorkDuration& message = messages[i]; new (mFmqTransaction.getSlot(i)) hal::ChannelMessage{ .sessionID = static_cast<int32_t>(config.id), - .timeStampNanos = (i == count - 1) ? now : message.timeStampNanos, + .timeStampNanos = + (i == count - 1) ? ::android::uptimeNanos() : message.timeStampNanos, .data = HalChannelMessageContents::make<HalChannelMessageContents::workDuration, hal::WorkDurationFixedV1>({ .durationNanos = message.cpuDurationNanos, @@ -688,8 +595,7 @@ void FMQWrapper::writeBuffer<HalChannelMessageContents::workDuration>(hal::WorkD } template <HalChannelMessageContents::Tag T, bool urgent, class C> -bool FMQWrapper::sendMessages(std::optional<hal::SessionConfig>& config, C* message, size_t count, - int64_t now) { +bool FMQWrapper::sendMessages(std::optional<hal::SessionConfig>& config, C* message, size_t count) { if (!isActiveLocked() || !config.has_value() || mCorrupted) { return false; } @@ -703,7 +609,7 @@ bool FMQWrapper::sendMessages(std::optional<hal::SessionConfig>& config, C* mess return false; } } - writeBuffer<T, C>(message, *config, count, now); + writeBuffer<T, C>(message, *config, count); mQueue->commitWrite(count); mEventFlag->wake(mWriteMask); // Re-create the persistent transaction after writing @@ -735,9 +641,10 @@ bool FMQWrapper::updateTargetWorkDuration(std::optional<hal::SessionConfig>& con return sendMessages<HalChannelMessageContents::targetDuration>(config, &targetDurationNanos); } -bool FMQWrapper::sendHints(std::optional<hal::SessionConfig>& config, - std::vector<hal::SessionHint>& hints, int64_t now) { - return sendMessages<HalChannelMessageContents::hint>(config, hints.data(), hints.size(), now); +bool FMQWrapper::sendHint(std::optional<hal::SessionConfig>& config, SessionHint hint) { + return sendMessages<HalChannelMessageContents::hint>(config, + reinterpret_cast<hal::SessionHint*>( + &hint)); } bool FMQWrapper::setMode(std::optional<hal::SessionConfig>& config, hal::SessionMode mode, @@ -851,9 +758,7 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) { int APerformanceHint_sendHint(APerformanceHintSession* session, SessionHint hint) { VALIDATE_PTR(session) - std::vector<hal::SessionHint> hints{static_cast<hal::SessionHint>(hint)}; - int64_t now = ::android::uptimeNanos(); - return session->sendHints(hints, now, "HWUI hint"); + return session->sendHint(hint); } int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds, @@ -886,26 +791,6 @@ int APerformanceHint_reportActualWorkDuration2(APerformanceHintSession* session, return session->reportActualWorkDuration(workDurationPtr); } -int APerformanceHint_notifyWorkloadIncrease(APerformanceHintSession* session, bool cpu, bool gpu, - const char* debugName) { - VALIDATE_PTR(session) - VALIDATE_PTR(debugName) - if (!useNewLoadHintBehavior()) { - return ENOTSUP; - } - return session->notifyWorkloadIncrease(cpu, gpu, debugName); -} - -int APerformanceHint_notifyWorkloadReset(APerformanceHintSession* session, bool cpu, bool gpu, - const char* debugName) { - VALIDATE_PTR(session) - VALIDATE_PTR(debugName) - if (!useNewLoadHintBehavior()) { - return ENOTSUP; - } - return session->notifyWorkloadReset(cpu, gpu, debugName); -} - AWorkDuration* AWorkDuration_create() { return new AWorkDuration(); } @@ -953,13 +838,3 @@ void APerformanceHint_setIHintManagerForTesting(void* iManager) { void APerformanceHint_setUseFMQForTesting(bool enabled) { gForceFMQEnabled = enabled; } - -void APerformanceHint_getRateLimiterPropertiesForTesting(int32_t* maxLoadHintsPerInterval, - int64_t* loadHintInterval) { - *maxLoadHintsPerInterval = kMaxLoadHintsPerInterval; - *loadHintInterval = kLoadHintInterval; -} - -void APerformanceHint_setUseNewLoadHintBehaviorForTesting(bool newBehavior) { - kForceNewHintBehavior = newBehavior; -} diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 5b4e1ea4e386..9de3a6f525e6 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -90,10 +90,7 @@ class PerformanceHintTest : public Test { public: void SetUp() override { mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>(); - APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval, - &mLoadHintInterval); APerformanceHint_setIHintManagerForTesting(&mMockIHintManager); - APerformanceHint_setUseNewLoadHintBehaviorForTesting(true); } void TearDown() override { @@ -179,9 +176,6 @@ public: int kMockQueueSize = 20; bool mUsingFMQ = false; - int32_t mMaxLoadHintsPerInterval; - int64_t mLoadHintInterval; - template <HalChannelMessageContents::Tag T, class C = HalChannelMessageContents::_at<T>> void expectToReadFromFmq(C expected) { hal::ChannelMessage readData; @@ -224,6 +218,7 @@ TEST_F(PerformanceHintTest, TestSession) { EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1)); result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos); EXPECT_EQ(0, result); + result = APerformanceHint_updateTargetWorkDuration(session, -1L); EXPECT_EQ(EINVAL, result); result = APerformanceHint_reportActualWorkDuration(session, -1L); @@ -233,28 +228,18 @@ TEST_F(PerformanceHintTest, TestSession) { EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1)); result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); - EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_UP))).Times(Exactly(1)); - result = APerformanceHint_notifyWorkloadIncrease(session, true, false, "Test hint"); + usleep(110000); // Sleep for longer than the update timeout. + EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1)); + result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); - EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_RESET))).Times(Exactly(1)); - EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_RESET))).Times(Exactly(1)); - result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint"); + // Expect to get rate limited if we try to send faster than the limiter allows + EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(0)); + result = APerformanceHint_sendHint(session, hintId); EXPECT_EQ(0, result); result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1)); EXPECT_EQ(EINVAL, result); - Mock::VerifyAndClearExpectations(mMockSession.get()); - for (int i = 0; i < mMaxLoadHintsPerInterval; ++i) { - APerformanceHint_sendHint(session, hintId); - } - - // Expect to get rate limited if we try to send faster than the limiter allows - EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0)); - result = APerformanceHint_notifyWorkloadIncrease(session, true, true, "Test hint"); - EXPECT_EQ(result, EBUSY); - EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0)); - result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint"); EXPECT_CALL(*mMockSession, close()).Times(Exactly(1)); APerformanceHint_closeSession(session); } |