diff options
author | 2022-11-11 18:28:12 +0000 | |
---|---|---|
committer | 2022-12-17 01:21:31 +0000 | |
commit | 095de769a6a821dffb5b6a5f59b4600671fe7c3f (patch) | |
tree | 9597754c28bfe245970e10869fd7792612a3b8f5 /native | |
parent | 13101fe9d27c41856fe09acb2831c88ebd729756 (diff) |
Implement setThreads APIs for PerformanceHintManager.Session.
Previously the list of threads of a Session was only determined when the
Session was created. This means newly forked threads from existing
threads of the Session will not get the benefit and the clients have to
create new Session for that.
This patch adds a new method to allow clients to update the threads of
the Session.
Bug:b/244216750
Test: atest PerformanceHintManagerTest
Test: atest PerformanceHintNativeTest
Test: atest HintManagerServiceTest
Change-Id: Iae8cbb4ce86a44a7cd9d6e68673c48800bed3a4e
Diffstat (limited to 'native')
-rw-r--r-- | native/android/libandroid.map.txt | 2 | ||||
-rw-r--r-- | native/android/performance_hint.cpp | 73 | ||||
-rw-r--r-- | native/android/tests/performance_hint/PerformanceHintNativeTest.cpp | 42 |
3 files changed, 110 insertions, 7 deletions
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 4e6a0c540f49..e89c8c9aa583 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -330,6 +330,7 @@ LIBANDROID { APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu APerformanceHint_closeSession; # introduced=Tiramisu + APerformanceHint_setThreads; # introduced=UpsideDownCake local: *; }; @@ -338,6 +339,7 @@ LIBANDROID_PLATFORM { global: APerformanceHint_setIHintManagerForTesting; APerformanceHint_sendHint; + APerformanceHint_getThreadIds; extern "C++" { ASurfaceControl_registerSurfaceStatsListener*; ASurfaceControl_unregisterSurfaceStatsListener*; diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 43b3d2e94aac..dfbd7b55a1f0 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -62,18 +62,21 @@ private: struct APerformanceHintSession { public: - APerformanceHintSession(sp<IHintSession> session, int64_t preferredRateNanos, - int64_t targetDurationNanos); + APerformanceHintSession(sp<IHintManager> hintManager, sp<IHintSession> session, + int64_t preferredRateNanos, int64_t targetDurationNanos); APerformanceHintSession() = delete; ~APerformanceHintSession(); int updateTargetWorkDuration(int64_t targetDurationNanos); int reportActualWorkDuration(int64_t actualDurationNanos); int sendHint(int32_t hint); + int setThreads(const int32_t* threadIds, size_t size); + int getThreadIds(int32_t* const threadIds, size_t* size); private: friend struct APerformanceHintManager; + sp<IHintManager> mHintManager; sp<IHintSession> mHintSession; // HAL preferred update rate const int64_t mPreferredRateNanos; @@ -140,7 +143,7 @@ APerformanceHintSession* APerformanceHintManager::createSession( if (!ret.isOk() || !session) { return nullptr; } - return new APerformanceHintSession(std::move(session), mPreferredRateNanos, + return new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos, initialTargetWorkDurationNanos); } @@ -150,10 +153,12 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const { // ===================================== APerformanceHintSession implementation -APerformanceHintSession::APerformanceHintSession(sp<IHintSession> session, +APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager, + sp<IHintSession> session, int64_t preferredRateNanos, int64_t targetDurationNanos) - : mHintSession(std::move(session)), + : mHintManager(hintManager), + mHintSession(std::move(session)), mPreferredRateNanos(preferredRateNanos), mTargetDurationNanos(targetDurationNanos), mFirstTargetMetTimestamp(0), @@ -260,6 +265,47 @@ int APerformanceHintSession::sendHint(int32_t hint) { return 0; } +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__); + return EINVAL; + } + std::vector<int32_t> tids(threadIds, threadIds + size); + binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids); + if (!ret.isOk()) { + ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); + if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY || + ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) { + return EINVAL; + } + return EPIPE; + } + return 0; +} + +int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) { + std::vector<int32_t> tids; + binder::Status ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids); + if (!ret.isOk()) { + ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); + return EPIPE; + } + + // When threadIds is nullptr, this is the first call to determine the size + // of the thread ids list. + if (threadIds == nullptr) { + *size = tids.size(); + return 0; + } + + // Second call to return the actual list of thread ids. + *size = tids.size(); + for (size_t i = 0; i < *size; ++i) { + threadIds[i] = tids[i]; + } + return 0; +} + // ===================================== C API APerformanceHintManager* APerformanceHint_getManager() { return APerformanceHintManager::getInstance(); @@ -293,6 +339,23 @@ int APerformanceHint_sendHint(void* session, int32_t hint) { return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint); } +int APerformanceHint_setThreads(APerformanceHintSession* session, const int32_t* threadIds, + size_t size) { + if (session == nullptr) { + return EINVAL; + } + return session->setThreads(threadIds, size); +} + +int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds, + size_t* const size) { + if (aPerformanceHintSession == nullptr) { + return EINVAL; + } + return static_cast<APerformanceHintSession*>(aPerformanceHintSession) + ->getThreadIds(threadIds, size); +} + void APerformanceHint_setIHintManagerForTesting(void* iManager) { delete gHintManagerForTesting; gHintManagerForTesting = nullptr; diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 0c2d3b6cd201..321a7dddb144 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -37,10 +37,15 @@ using namespace testing; class MockIHintManager : public IHintManager { public: MOCK_METHOD(Status, createHintSession, - (const ::android::sp<::android::IBinder>& token, const ::std::vector<int32_t>& tids, - int64_t durationNanos, ::android::sp<::android::os::IHintSession>* _aidl_return), + (const sp<IBinder>& token, const ::std::vector<int32_t>& tids, + int64_t durationNanos, ::android::sp<IHintSession>* _aidl_return), (override)); MOCK_METHOD(Status, getHintSessionPreferredRate, (int64_t * _aidl_return), (override)); + MOCK_METHOD(Status, setHintSessionThreads, + (const sp<IHintSession>& hintSession, const ::std::vector<int32_t>& tids), + (override)); + MOCK_METHOD(Status, getHintSessionThreadIds, + (const sp<IHintSession>& hintSession, ::std::vector<int32_t>* tids), (override)); MOCK_METHOD(IBinder*, onAsBinder, (), (override)); }; @@ -141,3 +146,36 @@ TEST_F(PerformanceHintTest, TestSession) { EXPECT_CALL(*iSession, close()).Times(Exactly(1)); APerformanceHint_closeSession(session); } + +TEST_F(PerformanceHintTest, SetThreads) { + APerformanceHintManager* manager = createManager(); + + std::vector<int32_t> tids; + tids.push_back(1); + tids.push_back(2); + int64_t targetDuration = 56789L; + + StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>(); + sp<IHintSession> session_sp(iSession); + + EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _)) + .Times(Exactly(1)) + .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status()))); + + APerformanceHintSession* session = + APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration); + ASSERT_TRUE(session); + + std::vector<int32_t> emptyTids; + int result = APerformanceHint_setThreads(session, emptyTids.data(), emptyTids.size()); + EXPECT_EQ(EINVAL, result); + + std::vector<int32_t> newTids; + newTids.push_back(1); + newTids.push_back(3); + EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))) + .Times(Exactly(1)) + .WillOnce(Return(Status())); + result = APerformanceHint_setThreads(session, newTids.data(), newTids.size()); + EXPECT_EQ(0, result); +} |