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

Commit 6ed6f6d8 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Refactor how timeouts are calculated."

parents 315f19be aa3855d5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -88,6 +88,16 @@ nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
nsecs_t systemTime(int clock);
#endif // def __cplusplus

/**
 * Returns the number of milliseconds to wait between the reference time and the timeout time.
 * If the timeout is in the past relative to the reference time, returns 0.
 * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time,
 * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay.
 * Otherwise, returns the difference between the reference time and timeout time
 * rounded up to the next millisecond.
 */
int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime);

#ifdef __cplusplus
} // extern "C"
#endif
+7 −12
Original line number Diff line number Diff line
@@ -218,14 +218,10 @@ int Looper::pollInner(int timeoutMillis) {
    // Adjust the timeout based on when the next message is due.
    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
        if (mNextMessageUptime <= now) {
            timeoutMillis = 0;
        } else {
            uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL;
            if (delay < INT_MAX
                    && (timeoutMillis < 0 || int(delay) < timeoutMillis)) {
                timeoutMillis = int(delay);
            }
        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
        if (messageTimeoutMillis >= 0
                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
            timeoutMillis = messageTimeoutMillis;
        }
#if DEBUG_POLL_AND_WAKE
        LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
@@ -444,12 +440,11 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat
                return result;
            }

            nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
            if (timeoutNanos <= 0) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
            if (timeoutMillis == 0) {
                return ALOOPER_POLL_TIMEOUT;
            }

            timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL));
        }
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <limits.h>

#ifdef HAVE_WIN32_THREADS
#include <windows.h>
@@ -53,6 +54,23 @@ nsecs_t systemTime(int clock)
#endif
}

int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
{
    int timeoutDelayMillis;
    if (timeoutTime > referenceTime) {
        uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
        if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
            timeoutDelayMillis = -1;
        } else {
            timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
        }
    } else {
        timeoutDelayMillis = 0;
    }
    return timeoutDelayMillis;
}


/*
 * ===========================================================================
 *      DurationTimer
+10 −3
Original line number Diff line number Diff line
@@ -445,7 +445,7 @@ EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
    return NULL;
}

bool EventHub::getEvent(RawEvent* outEvent) {
bool EventHub::getEvent(int timeoutMillis, RawEvent* outEvent) {
    outEvent->deviceId = 0;
    outEvent->type = 0;
    outEvent->scanCode = 0;
@@ -598,13 +598,20 @@ bool EventHub::getEvent(RawEvent* outEvent) {
        // when this happens, the EventHub holds onto its own user wake lock while the client
        // is processing events.  Thus the system can only sleep if there are no events
        // pending or currently being processed.
        //
        // The timeout is advisory only.  If the device is asleep, it will not wake just to
        // service the timeout.
        release_wake_lock(WAKE_LOCK_ID);

        int pollResult = poll(mFds.editArray(), mFds.size(), -1);
        int pollResult = poll(mFds.editArray(), mFds.size(), timeoutMillis);

        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

        if (pollResult <= 0) {
        if (pollResult == 0) {
            // Timed out.
            return false;
        }
        if (pollResult < 0) {
            if (errno != EINTR) {
                LOGW("poll failed (errno=%d)\n", errno);
                usleep(100000);
+7 −2
Original line number Diff line number Diff line
@@ -186,8 +186,13 @@ public:
     * This ensures that the device will not go to sleep while the event is being processed.
     * If the device needs to remain awake longer than that, then the caller is responsible
     * for taking care of it (say, by poking the power manager user activity timer).
     *
     * The timeout is advisory only.  If the device is asleep, it will not wake just to
     * service the timeout.
     *
     * Returns true if an event was obtained, false if the timeout expired.
     */
    virtual bool getEvent(RawEvent* outEvent) = 0;
    virtual bool getEvent(int timeoutMillis, RawEvent* outEvent) = 0;

    /*
     * Query current input state.
@@ -244,7 +249,7 @@ public:
    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
            const int32_t* keyCodes, uint8_t* outFlags) const;

    virtual bool getEvent(RawEvent* outEvent);
    virtual bool getEvent(int timeoutMillis, RawEvent* outEvent);

    virtual bool hasLed(int32_t deviceId, int32_t led) const;
    virtual void setLedState(int32_t deviceId, int32_t led, bool on);
Loading