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

Commit c5c5bd8d authored by Alec Mouri's avatar Alec Mouri Committed by Automerger Merge Worker
Browse files

Merge "Tweak wakeup time for OneShotTimer to reduce jank" into tm-dev am: 57a40d9d am: 0ca9e31d

parents 48036751 0ca9e31d
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -118,17 +118,18 @@ void OneShotTimer::loop() {
        auto triggerTime = mClock->now() + mInterval;
        state = TimerState::WAITING;
        while (true) {
            // Wait until triggerTime time to check if we need to reset or drop into the idle state.
            if (const auto triggerInterval = triggerTime - mClock->now(); triggerInterval > 0ns) {
                mWaiting = true;
            constexpr auto zero = std::chrono::steady_clock::duration::zero();
            // Wait for mInterval time to check if we need to reset or drop into the idle state.
                struct timespec ts;
            calculateTimeoutTime(std::chrono::nanoseconds(mInterval), &ts);
                calculateTimeoutTime(triggerInterval, &ts);
                int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts);
                if (result && errno != ETIMEDOUT && errno != EINTR) {
                    std::stringstream ss;
                    ss << "sem_clockwait failed (" << errno << ")";
                    LOG_ALWAYS_FATAL("%s", ss.str().c_str());
                }
            }

            mWaiting = false;
            state = checkForResetAndStop(state);
@@ -136,7 +137,7 @@ void OneShotTimer::loop() {
                break;
            }

            if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= zero) {
            if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= 0ns) {
                triggerTimeout = true;
                state = TimerState::IDLE;
                break;
+34 −0
Original line number Diff line number Diff line
@@ -130,6 +130,40 @@ TEST_F(OneShotTimerTest, DISABLED_resetBackToBackTest) {
    EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
}

// TODO(b/186417847) This test is new and passes locally, but may be flaky
TEST_F(OneShotTimerTest, DISABLED_resetBackToBackSlowAdvanceTest) {
    fake::FakeClock* clock = new fake::FakeClock();
    mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                           mResetTimerCallback.getInvocable(),
                                                           mExpiredTimerCallback.getInvocable(),
                                                           std::unique_ptr<fake::FakeClock>(clock));
    mIdleTimer->start();
    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());

    mIdleTimer->reset();
    EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
    EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value());

    clock->advanceTime(200us);
    mIdleTimer->reset();

    // Normally we would check that the timer callbacks weren't invoked here
    // after resetting the timer, but we need to precisely control the timing of
    // this test, and checking that callbacks weren't invoked requires non-zero
    // time.

    clock->advanceTime(1500us);
    EXPECT_TRUE(mExpiredTimerCallback.waitForCall(1100us).has_value());
    mIdleTimer->reset();
    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());

    mIdleTimer->stop();
    clock->advanceTime(2ms);
    // Final quick check that no more callback were observed.
    EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value());
    EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
}

TEST_F(OneShotTimerTest, startNotCalledTest) {
    fake::FakeClock* clock = new fake::FakeClock();
    mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,