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

Commit a7291156 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "TimedEventQueue: improve wakelock management" into klp-dev

parents 51ac2d64 e8332ee3
Loading
Loading
Loading
Loading
+52 −42
Original line number Diff line number Diff line
@@ -38,11 +38,14 @@

namespace android {

static int64_t kWakelockMinDelay = 100000ll;  // 100ms

TimedEventQueue::TimedEventQueue()
    : mNextEventID(1),
      mRunning(false),
      mStopped(false),
      mDeathRecipient(new PMDeathRecipient(this)) {
      mDeathRecipient(new PMDeathRecipient(this)),
      mWakeLockCount(0) {
}

TimedEventQueue::~TimedEventQueue() {
@@ -87,9 +90,7 @@ void TimedEventQueue::stop(bool flush) {

    // some events may be left in the queue if we did not flush and the wake lock
    // must be released.
    if (!mQueue.empty()) {
        releaseWakeLock_l();
    }
    releaseWakeLock_l(true /*force*/);
    mQueue.clear();

    mRunning = false;
@@ -126,13 +127,15 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent(
    QueueItem item;
    item.event = event;
    item.realtime_us = realtime_us;
    item.has_wakelock = false;

    if (it == mQueue.begin()) {
        mQueueHeadChangedCondition.signal();
    }

    if (mQueue.empty()) {
    if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) {
        acquireWakeLock_l();
        item.has_wakelock = true;
    }
    mQueue.insert(it, item);

@@ -188,10 +191,10 @@ void TimedEventQueue::cancelEvents(
        ALOGV("cancelling event %d", (*it).event->eventID());

        (*it).event->setEventID(0);
        it = mQueue.erase(it);
        if (mQueue.empty()) {
        if ((*it).has_wakelock) {
            releaseWakeLock_l();
        }
        it = mQueue.erase(it);
        if (stopAfterFirstMatch) {
            return;
        }
@@ -297,11 +300,10 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
        if ((*it).event->eventID() == id) {
            sp<Event> event = (*it).event;
            event->setEventID(0);

            mQueue.erase(it);
            if (mQueue.empty()) {
            if ((*it).has_wakelock) {
                releaseWakeLock_l();
            }
            mQueue.erase(it);
            return event;
        }
    }
@@ -313,9 +315,8 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(

void TimedEventQueue::acquireWakeLock_l()
{
    if (mWakeLockToken != 0) {
        return;
    }
    if (mWakeLockCount++ == 0) {
        CHECK(mWakeLockToken == 0);
        if (mPowerManager == 0) {
            // use checkService() to avoid blocking if power service is not up yet
            sp<IBinder> binder =
@@ -340,12 +341,20 @@ void TimedEventQueue::acquireWakeLock_l()
            }
        }
    }
}

void TimedEventQueue::releaseWakeLock_l()
void TimedEventQueue::releaseWakeLock_l(bool force)
{
    if (mWakeLockToken == 0) {
    if (force) {
        if (mWakeLockCount == 0) {
            return;
        }
        // Force wakelock release below by setting reference count to 1.
        mWakeLockCount = 1;
    }
    CHECK(mWakeLockCount != 0);
    if (--mWakeLockCount == 0) {
        CHECK(mWakeLockToken != 0);
        if (mPowerManager != 0) {
            int64_t token = IPCThreadState::self()->clearCallingIdentity();
            mPowerManager->releaseWakeLock(mWakeLockToken, 0);
@@ -353,11 +362,12 @@ void TimedEventQueue::releaseWakeLock_l()
        }
        mWakeLockToken.clear();
    }
}

void TimedEventQueue::clearPowerManager()
{
    Mutex::Autolock _l(mLock);
    releaseWakeLock_l();
    releaseWakeLock_l(true /*force*/);
    mPowerManager.clear();
}

+3 −1
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ private:
    struct QueueItem {
        sp<Event> event;
        int64_t realtime_us;
        bool has_wakelock;
    };

    struct StopEvent : public TimedEventQueue::Event {
@@ -139,6 +140,7 @@ private:
    sp<IPowerManager>       mPowerManager;
    sp<IBinder>             mWakeLockToken;
    const sp<PMDeathRecipient> mDeathRecipient;
    uint32_t                mWakeLockCount;

    static void *ThreadWrapper(void *me);
    void threadEntry();
@@ -146,7 +148,7 @@ private:
    sp<Event> removeEventFromQueue_l(event_id id);

    void acquireWakeLock_l();
    void releaseWakeLock_l();
    void releaseWakeLock_l(bool force = false);

    TimedEventQueue(const TimedEventQueue &);
    TimedEventQueue &operator=(const TimedEventQueue &);