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

Commit 7235ddab authored by Alec Mouri's avatar Alec Mouri Committed by Android (Google) Code Review
Browse files

Merge "Reduce gratuitous resets for OneShotTimer" into tm-dev

parents 2b9326b1 aadcf949
Loading
Loading
Loading
Loading
+23 −8
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ OneShotTimer::OneShotTimer(std::string name, const Interval& interval,
        mInterval(interval),
        mInterval(interval),
        mResetCallback(resetCallback),
        mResetCallback(resetCallback),
        mTimeoutCallback(timeoutCallback) {
        mTimeoutCallback(timeoutCallback) {
    mLastResetTime = std::chrono::steady_clock::time_point::min();
    LOG_ALWAYS_FATAL_IF(!mClock, "Clock must not be provided");
    LOG_ALWAYS_FATAL_IF(!mClock, "Clock must not be provided");
}
}


@@ -116,9 +117,10 @@ void OneShotTimer::loop() {


        auto triggerTime = mClock->now() + mInterval;
        auto triggerTime = mClock->now() + mInterval;
        state = TimerState::WAITING;
        state = TimerState::WAITING;
        while (state == TimerState::WAITING) {
        while (true) {
            mWaiting = true;
            constexpr auto zero = std::chrono::steady_clock::duration::zero();
            constexpr auto zero = std::chrono::steady_clock::duration::zero();
            // Wait for mInterval time for semaphore signal.
            // Wait for mInterval time to check if we need to reset or drop into the idle state.
            struct timespec ts;
            struct timespec ts;
            calculateTimeoutTime(std::chrono::nanoseconds(mInterval), &ts);
            calculateTimeoutTime(std::chrono::nanoseconds(mInterval), &ts);
            int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts);
            int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts);
@@ -128,13 +130,21 @@ void OneShotTimer::loop() {
                LOG_ALWAYS_FATAL("%s", ss.str().c_str());
                LOG_ALWAYS_FATAL("%s", ss.str().c_str());
            }
            }


            mWaiting = false;
            state = checkForResetAndStop(state);
            state = checkForResetAndStop(state);
            if (state == TimerState::RESET) {
            if (state == TimerState::STOPPED) {
                triggerTime = mClock->now() + mInterval;
                break;
                state = TimerState::WAITING;
            }
            } else if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= zero) {

            if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= zero) {
                triggerTimeout = true;
                triggerTimeout = true;
                state = TimerState::IDLE;
                state = TimerState::IDLE;
                break;
            }

            if (state == TimerState::RESET) {
                triggerTime = mLastResetTime.load() + mInterval;
                state = TimerState::WAITING;
            }
            }
        }
        }


@@ -158,9 +168,14 @@ OneShotTimer::TimerState OneShotTimer::checkForResetAndStop(TimerState state) {
}
}


void OneShotTimer::reset() {
void OneShotTimer::reset() {
    mLastResetTime = mClock->now();
    mResetTriggered = true;
    mResetTriggered = true;
    int result = sem_post(&mSemaphore);
    // If mWaiting is true, then we are guaranteed to be in a block where we are waiting on
    LOG_ALWAYS_FATAL_IF(result, "sem_post failed");
    // mSemaphore for a timeout, rather than idling. So we can avoid a sem_post call since we can
    // just check that we triggered a reset on timeout.
    if (!mWaiting) {
        LOG_ALWAYS_FATAL_IF(sem_post(&mSemaphore), "sem_post failed");
    }
}
}


std::string OneShotTimer::dump() const {
std::string OneShotTimer::dump() const {
+2 −0
Original line number Original line Diff line number Diff line
@@ -103,6 +103,8 @@ private:
    // check in the main loop if they were.
    // check in the main loop if they were.
    std::atomic<bool> mResetTriggered = false;
    std::atomic<bool> mResetTriggered = false;
    std::atomic<bool> mStopTriggered = false;
    std::atomic<bool> mStopTriggered = false;
    std::atomic<bool> mWaiting = false;
    std::atomic<std::chrono::steady_clock::time_point> mLastResetTime;
};
};


} // namespace scheduler
} // namespace scheduler