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

Commit 0cda3185 authored by Xiang Wang's avatar Xiang Wang Committed by Automerger Merge Worker
Browse files

Merge "Adjust actual work duration when target time is changed within allowed...

Merge "Adjust actual work duration when target time is changed within allowed deviation limit" into tm-dev am: e3012a10 am: 9bc81bd3

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/17606044



Change-Id: I8b7a09f48149b9e481342a0075961f8eb56b1f0f
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents f3dcff52 9bc81bd3
Loading
Loading
Loading
Loading
+25 −13
Original line number Original line Diff line number Diff line
@@ -463,29 +463,41 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos,
        ALOGV("Failed to send actual work duration, skipping");
        ALOGV("Failed to send actual work duration, skipping");
        return;
        return;
    }
    }

    nsecs_t reportedDuration = actualDurationNanos;
    WorkDuration duration;
    duration.durationNanos = actualDurationNanos;
    mActualDuration = actualDurationNanos;


    // normalize the sent values to a pre-set target
    // normalize the sent values to a pre-set target
    if (sNormalizeTarget) {
    if (sNormalizeTarget) {
        duration.durationNanos += mLastTargetDurationSent - mTargetDuration;
        reportedDuration += mLastTargetDurationSent - mTargetDuration;
    }
    } else {
        // when target duration change is within deviation and not updated, adjust the actual
        // duration proportionally based on the difference, e.g. if new target is 5ms longer than
        // last reported but actual duration is the same as last target, we want to report a smaller
        // actual work duration now to indicate that we are overshooting
        if (mLastTargetDurationSent != kDefaultTarget.count() && mTargetDuration != 0) {
            reportedDuration =
                    static_cast<int64_t>(static_cast<long double>(mLastTargetDurationSent) /
                                         mTargetDuration * actualDurationNanos);
            mActualDuration = reportedDuration;
        }
    }
    mActualDuration = reportedDuration;
    WorkDuration duration;
    duration.durationNanos = reportedDuration;
    duration.timeStampNanos = timeStampNanos;
    duration.timeStampNanos = timeStampNanos;
    mPowerHintQueue.push_back(duration);
    mPowerHintQueue.push_back(duration);


    nsecs_t targetNsec = mTargetDuration;
    nsecs_t durationNsec = actualDurationNanos;

    if (sTraceHintSessionData) {
    if (sTraceHintSessionData) {
        ATRACE_INT64("Measured duration", durationNsec);
        ATRACE_INT64("Measured duration", actualDurationNanos);
        ATRACE_INT64("Target error term", targetNsec - durationNsec);
        ATRACE_INT64("Target error term", mTargetDuration - actualDurationNanos);

        ATRACE_INT64("Reported duration", reportedDuration);
        ATRACE_INT64("Reported target", mLastTargetDurationSent);
        ATRACE_INT64("Reported target error term", mLastTargetDurationSent - reportedDuration);
    }
    }


    ALOGV("Sending actual work duration of: %" PRId64 " on target: %" PRId64
    ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64
          " with error: %" PRId64,
          " with error: %" PRId64,
          durationNsec, targetNsec, targetNsec - durationNsec);
          reportedDuration, mLastTargetDurationSent, mLastTargetDurationSent - reportedDuration);


    // This rate limiter queues similar duration reports to the powerhal into
    // This rate limiter queues similar duration reports to the powerhal into
    // batches to avoid excessive binder calls. The criteria to send a given batch
    // batches to avoid excessive binder calls. The criteria to send a given batch
@@ -501,7 +513,7 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos,
        }
        }
        mPowerHintQueue.clear();
        mPowerHintQueue.clear();
        // we save the non-normalized value here to detect % changes
        // we save the non-normalized value here to detect % changes
        mLastActualDurationSent = actualDurationNanos;
        mLastActualDurationSent = reportedDuration;
    }
    }
}
}


+2 −2
Original line number Original line Diff line number Diff line
@@ -173,8 +173,8 @@ private:


    // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
    // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
    static constexpr double kAllowedActualDeviationPercent = 0.1;
    static constexpr double kAllowedActualDeviationPercent = 0.1;
    // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%)
    // Max percent the target duration can vary without causing a report (eg: 0.1 = 10%)
    static constexpr double kAllowedTargetDeviationPercent = 0.05;
    static constexpr double kAllowedTargetDeviationPercent = 0.1;
    // Target used for init and normalization, the actual value does not really matter
    // Target used for init and normalization, the actual value does not really matter
    static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
    static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
    // Amount of time after the last message was sent before the session goes stale
    // Amount of time after the last message was sent before the session goes stale
+46 −2
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#undef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "AidlPowerHalWrapperTest"
#define LOG_TAG "AidlPowerHalWrapperTest"


#include <android-base/stringprintf.h>
#include <android/hardware/power/IPower.h>
#include <android/hardware/power/IPower.h>
#include <android/hardware/power/IPowerHintSession.h>
#include <android/hardware/power/IPowerHintSession.h>
#include <gmock/gmock.h>
#include <gmock/gmock.h>
@@ -82,6 +83,15 @@ WorkDuration toWorkDuration(std::chrono::nanoseconds durationNanos, int64_t time
    return duration;
    return duration;
}
}


std::string printWorkDurations(const ::std::vector<WorkDuration>& durations) {
    std::ostringstream os;
    for (auto duration : durations) {
        os << duration.toString();
        os << "\n";
    }
    return os.str();
}

namespace {
namespace {
TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) {
TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) {
    ASSERT_TRUE(mWrapper->supportsPowerHintSession());
    ASSERT_TRUE(mWrapper->supportsPowerHintSession());
@@ -143,8 +153,8 @@ TEST_F(AidlPowerHalWrapperTest, setTargetWorkDuration) {
                                                                              {-1ms, false},
                                                                              {-1ms, false},
                                                                              {200ms, true},
                                                                              {200ms, true},
                                                                              {2ms, true},
                                                                              {2ms, true},
                                                                              {96ms, false},
                                                                              {91ms, false},
                                                                              {104ms, false}};
                                                                              {109ms, false}};


    for (const auto& test : testCases) {
    for (const auto& test : testCases) {
        // reset to 100ms baseline
        // reset to 100ms baseline
@@ -212,6 +222,40 @@ TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration) {
    }
    }
}
}


TEST_F(AidlPowerHalWrapperTest, sendAdjustedActualWorkDuration) {
    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();

    std::chrono::nanoseconds lastTarget = 100ms;
    EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(lastTarget.count())).Times(1);
    mWrapper->setTargetWorkDuration(lastTarget.count());
    std::chrono::nanoseconds newTarget = 105ms;
    mWrapper->setTargetWorkDuration(newTarget.count());
    EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(newTarget.count())).Times(0);
    std::chrono::nanoseconds actual = 21ms;
    // 100 / 105 * 21ms = 20ms
    std::chrono::nanoseconds expectedActualSent = 20ms;
    std::vector<WorkDuration> expectedDurations = {toWorkDuration(expectedActualSent, 1)};

    EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_))
            .WillOnce(DoAll(
                    [expectedDurations](const ::std::vector<WorkDuration>& durationsSent) {
                        EXPECT_EQ(expectedDurations, durationsSent)
                                << base::StringPrintf("actual sent: %s vs expected: %s",
                                                      printWorkDurations(durationsSent).c_str(),
                                                      printWorkDurations(expectedDurations)
                                                              .c_str());
                    },
                    Return(Status::ok())));
    mWrapper->sendActualWorkDuration(actual.count(), 1);
}

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