Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fb0b2a4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove rate limiter from adpf cpu hint session"

parents 6c3f9792 44e612e8
Loading
Loading
Loading
Loading
+6 −37
Original line number Original line Diff line number Diff line
@@ -640,9 +640,6 @@ AidlPowerHalWrapper::AidlPowerHalWrapper(sp<IPower> powerHal) : mPowerHal(std::m
    }
    }


    mSupportsPowerHint = checkPowerHintSessionSupported();
    mSupportsPowerHint = checkPowerHintSessionSupported();

    // Currently set to 0 to disable rate limiter by default
    mAllowedActualDeviation = base::GetIntProperty<nsecs_t>("debug.sf.allowed_actual_deviation", 0);
}
}


AidlPowerHalWrapper::~AidlPowerHalWrapper() {
AidlPowerHalWrapper::~AidlPowerHalWrapper() {
@@ -758,21 +755,6 @@ void AidlPowerHalWrapper::setTargetWorkDuration(int64_t targetDuration) {
    }
    }
}
}


bool AidlPowerHalWrapper::shouldReportActualDurations() {
    // Report if we have never reported before or will go stale next frame
    if (!mLastActualDurationSent.has_value() ||
        (mLastTargetDurationSent + systemTime() - mLastActualReportTimestamp) >
                kStaleTimeout.count()) {
        return true;
    }

    if (!mActualDuration.has_value()) {
        return false;
    }
    // Report if the change in actual duration exceeds the threshold
    return abs(*mActualDuration - *mLastActualDurationSent) > mAllowedActualDeviation;
}

void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDuration, nsecs_t timestamp) {
void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDuration, nsecs_t timestamp) {
    ATRACE_CALL();
    ATRACE_CALL();


@@ -801,12 +783,6 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDuration, nsecs_t
          " with error: %" PRId64,
          " with error: %" PRId64,
          reportedDuration, mLastTargetDurationSent, reportedDuration - mLastTargetDurationSent);
          reportedDuration, mLastTargetDurationSent, reportedDuration - mLastTargetDurationSent);


    // This rate limiter queues similar duration reports to the powerhal into
    // batches to avoid excessive binder calls. The criteria to send a given batch
    // are outlined in shouldReportActualDurationsNow()
    if (shouldReportActualDurations()) {
        ALOGV("Sending hint update batch");
        mLastActualReportTimestamp = systemTime();
    auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
    auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
    if (!ret.isOk()) {
    if (!ret.isOk()) {
        ALOGW("Failed to report actual work durations with error: %s",
        ALOGW("Failed to report actual work durations with error: %s",
@@ -814,9 +790,6 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDuration, nsecs_t
        mShouldReconnectHal = true;
        mShouldReconnectHal = true;
    }
    }
    mPowerHintQueue.clear();
    mPowerHintQueue.clear();
        // We save the actual duration here for rate limiting
        mLastActualDurationSent = actualDuration;
    }
}
}


bool AidlPowerHalWrapper::shouldReconnectHAL() {
bool AidlPowerHalWrapper::shouldReconnectHAL() {
@@ -831,10 +804,6 @@ std::optional<int64_t> AidlPowerHalWrapper::getTargetWorkDuration() {
    return mTargetDuration;
    return mTargetDuration;
}
}


void AidlPowerHalWrapper::setAllowedActualDeviation(nsecs_t allowedDeviation) {
    mAllowedActualDeviation = allowedDeviation;
}

const bool AidlPowerHalWrapper::sTraceHintSessionData =
const bool AidlPowerHalWrapper::sTraceHintSessionData =
        base::GetBoolProperty(std::string("debug.sf.trace_hint_sessions"), false);
        base::GetBoolProperty(std::string("debug.sf.trace_hint_sessions"), false);


+0 −13
Original line number Original line Diff line number Diff line
@@ -305,10 +305,6 @@ private:


    bool checkPowerHintSessionSupported();
    bool checkPowerHintSessionSupported();
    void closePowerHintSession();
    void closePowerHintSession();
    bool shouldReportActualDurations();

    // Used for testing
    void setAllowedActualDeviation(nsecs_t);


    const sp<hardware::power::IPower> mPowerHal = nullptr;
    const sp<hardware::power::IPower> mPowerHal = nullptr;
    bool mHasExpensiveRendering = false;
    bool mHasExpensiveRendering = false;
@@ -328,19 +324,10 @@ private:
    // The list of thread ids, stored so we can restart the session from this class if needed
    // The list of thread ids, stored so we can restart the session from this class if needed
    std::vector<int32_t> mPowerHintThreadIds;
    std::vector<int32_t> mPowerHintThreadIds;
    bool mSupportsPowerHint = false;
    bool mSupportsPowerHint = false;
    // Keep track of the last messages sent for rate limiter change detection
    std::optional<nsecs_t> mLastActualDurationSent;
    // Timestamp of the last report we sent, used to avoid stale sessions
    nsecs_t mLastActualReportTimestamp = 0;
    nsecs_t mLastTargetDurationSent = kDefaultTarget.count();
    nsecs_t mLastTargetDurationSent = kDefaultTarget.count();
    // Max amount the error term can vary without causing an actual value report
    nsecs_t mAllowedActualDeviation = -1;
    // Whether we should emit ATRACE_INT data for hint sessions
    // Whether we should emit ATRACE_INT data for hint sessions
    static const bool sTraceHintSessionData;
    static const bool sTraceHintSessionData;
    static constexpr const std::chrono::nanoseconds kDefaultTarget = 16ms;
    static constexpr const std::chrono::nanoseconds kDefaultTarget = 16ms;
    // Amount of time after the last message was sent before the session goes stale
    // actually 100ms but we use 80 here to give some slack
    static constexpr const std::chrono::nanoseconds kStaleTimeout = 80ms;
};
};


} // namespace impl
} // namespace impl
+12 −55
Original line number Original line Diff line number Diff line
@@ -50,10 +50,8 @@ protected:
    sp<NiceMock<MockIPower>> mMockHal = nullptr;
    sp<NiceMock<MockIPower>> mMockHal = nullptr;
    sp<NiceMock<MockIPowerHintSession>> mMockSession = nullptr;
    sp<NiceMock<MockIPowerHintSession>> mMockSession = nullptr;
    void verifyAndClearExpectations();
    void verifyAndClearExpectations();
    void sendActualWorkDurationGroup(std::vector<WorkDuration> durations,
    void sendActualWorkDurationGroup(std::vector<WorkDuration> durations);
                                     std::chrono::nanoseconds sleepBeforeLastSend);
    static constexpr std::chrono::duration kStaleTimeout = 100ms;
    std::chrono::nanoseconds mAllowedDeviation;
    std::chrono::nanoseconds mStaleTimeout;
};
};


void AidlPowerHalWrapperTest::SetUp() {
void AidlPowerHalWrapperTest::SetUp() {
@@ -61,9 +59,6 @@ void AidlPowerHalWrapperTest::SetUp() {
    mMockSession = sp<NiceMock<MockIPowerHintSession>>::make();
    mMockSession = sp<NiceMock<MockIPowerHintSession>>::make();
    ON_CALL(*mMockHal.get(), getHintSessionPreferredRate(_)).WillByDefault(Return(Status::ok()));
    ON_CALL(*mMockHal.get(), getHintSessionPreferredRate(_)).WillByDefault(Return(Status::ok()));
    mWrapper = std::make_unique<AidlPowerHalWrapper>(mMockHal);
    mWrapper = std::make_unique<AidlPowerHalWrapper>(mMockHal);
    mWrapper->setAllowedActualDeviation(std::chrono::nanoseconds{10ms}.count());
    mAllowedDeviation = std::chrono::nanoseconds{mWrapper->mAllowedActualDeviation};
    mStaleTimeout = AidlPowerHalWrapper::kStaleTimeout;
}
}


void AidlPowerHalWrapperTest::verifyAndClearExpectations() {
void AidlPowerHalWrapperTest::verifyAndClearExpectations() {
@@ -71,12 +66,8 @@ void AidlPowerHalWrapperTest::verifyAndClearExpectations() {
    Mock::VerifyAndClearExpectations(mMockSession.get());
    Mock::VerifyAndClearExpectations(mMockSession.get());
}
}


void AidlPowerHalWrapperTest::sendActualWorkDurationGroup(
void AidlPowerHalWrapperTest::sendActualWorkDurationGroup(std::vector<WorkDuration> durations) {
        std::vector<WorkDuration> durations, std::chrono::nanoseconds sleepBeforeLastSend) {
    for (size_t i = 0; i < durations.size(); i++) {
    for (size_t i = 0; i < durations.size(); i++) {
        if (i == durations.size() - 1) {
            std::this_thread::sleep_for(sleepBeforeLastSend);
        }
        auto duration = durations[i];
        auto duration = durations[i];
        mWrapper->sendActualWorkDuration(duration.durationNanos, duration.timeStampNanos);
        mWrapper->sendActualWorkDuration(duration.durationNanos, duration.timeStampNanos);
    }
    }
@@ -206,58 +197,24 @@ TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration) {
    // 100ms
    // 100ms
    const std::vector<std::pair<std::vector<std::pair<std::chrono::nanoseconds, nsecs_t>>, bool>>
    const std::vector<std::pair<std::vector<std::pair<std::chrono::nanoseconds, nsecs_t>>, bool>>
            testCases = {{{{-1ms, 100}}, false},
            testCases = {{{{-1ms, 100}}, false},
                         {{{100ms - (mAllowedDeviation / 2), 100}}, false},
                         {{{50ms, 100}}, true},
                         {{{100ms + (mAllowedDeviation / 2), 100}}, false},
                         {{{100ms + (mAllowedDeviation + 1ms), 100}}, true},
                         {{{100ms - (mAllowedDeviation + 1ms), 100}}, true},
                         {{{100ms, 100}, {200ms, 200}}, true},
                         {{{100ms, 100}, {200ms, 200}}, true},
                         {{{100ms, 500}, {100ms, 600}, {3ms, 600}}, true}};
                         {{{100ms, 500}, {100ms, 600}, {3ms, 600}}, true}};


    for (const auto& test : testCases) {
    for (const auto& test : testCases) {
        // reset actual duration
        // reset actual duration
        sendActualWorkDurationGroup({base}, mStaleTimeout);
        sendActualWorkDurationGroup({base});


        auto raw = test.first;
        auto raw = test.first;
        std::vector<WorkDuration> durations(raw.size());
        std::vector<WorkDuration> durations(raw.size());
        std::transform(raw.begin(), raw.end(), durations.begin(),
        std::transform(raw.begin(), raw.end(), durations.begin(),
                       [](auto d) { return toWorkDuration(d); });
                       [](auto d) { return toWorkDuration(d); });
        EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(durations))
        for (auto& duration : durations) {
            EXPECT_CALL(*mMockSession.get(),
                        reportActualWorkDuration(std::vector<WorkDuration>{duration}))
                    .Times(test.second ? 1 : 0);
                    .Times(test.second ? 1 : 0);
        sendActualWorkDurationGroup(durations, 0ms);
        verifyAndClearExpectations();
    }
        }
        }

        sendActualWorkDurationGroup(durations);
TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_exceedsStaleTime) {
    ASSERT_TRUE(mWrapper->supportsPowerHintSession());

    std::vector<int32_t> threadIds = {1, 2};
    mWrapper->setPowerHintSessionThreadIds(threadIds);
    EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
            .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
    ASSERT_TRUE(mWrapper->startPowerHintSession());
    verifyAndClearExpectations();

    auto base = toWorkDuration(100ms, 0);
    // test cases with actual work durations and whether it should update hint against baseline
    // 100ms
    const std::vector<std::tuple<std::vector<std::pair<std::chrono::nanoseconds, nsecs_t>>,
                                 std::chrono::nanoseconds, bool>>
            testCases = {{{{100ms, 100}}, mStaleTimeout, true},
                         {{{100ms + (mAllowedDeviation / 2), 100}}, mStaleTimeout, true},
                         {{{100ms, 100}}, mStaleTimeout / 2, false}};

    for (const auto& test : testCases) {
        // reset actual duration
        sendActualWorkDurationGroup({base}, mStaleTimeout);

        auto raw = std::get<0>(test);
        std::vector<WorkDuration> durations(raw.size());
        std::transform(raw.begin(), raw.end(), durations.begin(),
                       [](auto d) { return toWorkDuration(d); });
        EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(durations))
                .Times(std::get<2>(test) ? 1 : 0);
        sendActualWorkDurationGroup(durations, std::get<1>(test));
        verifyAndClearExpectations();
        verifyAndClearExpectations();
    }
    }
}
}
@@ -275,7 +232,7 @@ TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_shouldReconnectOnError) {
    duration.durationNanos = 1;
    duration.durationNanos = 1;
    EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_))
    EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_))
            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE)));
            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE)));
    sendActualWorkDurationGroup({duration}, 0ms);
    sendActualWorkDurationGroup({duration});
    EXPECT_TRUE(mWrapper->shouldReconnectHAL());
    EXPECT_TRUE(mWrapper->shouldReconnectHAL());
}
}