zoukankan      html  css  js  c++  java
  • android STR suspend trigger

    android STR suspend trigger

    void SystemSuspend::initAutosuspend() {
    std::thread autosuspendThread([this] {
    while (true) {
    std::this_thread::sleep_for(mSleepTime);
    lseek(mWakeupCountFd, 0, SEEK_SET);
    const string wakeupCount = readFd(mWakeupCountFd);
    if (wakeupCount.empty()) {
    PLOG(ERROR) << "error reading from /sys/power/wakeup_count";
    continue;
    }
    auto counterLock = std::unique_lock(mCounterLock);
    mCounterCondVar.wait(counterLock, [this] { return mSuspendCounter == 0; });
    // The mutex is locked and *MUST* remain locked until we write to /sys/power/state.
    // Otherwise, a WakeLock might be acquired after we check mSuspendCounter and before we
    // write to /sys/power/state.
    if (!WriteStringToFd(wakeupCount, mWakeupCountFd)) {
    PLOG(VERBOSE) << "error writing from /sys/power/wakeup_count";
    continue;
    }
    bool success = WriteStringToFd(kSleepState, mStateFd);
    counterLock.unlock();
    if (!success) {
    PLOG(VERBOSE) << "error writing to /sys/power/state";
    }
    mControlService->notifyWakeup(success);
    updateSleepTime(success);
    }
    });
    autosuspendThread.detach();
    LOG(INFO) << "automatic system suspend enabled";
    }

    然后WriteStringToFd(wakeupCount, mWakeupCountFd)将上面readFd返回的wakeup cnt写入/sys/power/wakeup_count,这将会call到kernel的pm_save_wakeup_count,如果传下来的count和kernel里的wakeup count相等,并且没有in progress wakeup source,这个函数将返回true;否则返回false。上面readFd(mWakeupCountFd)是一个阻塞调用,如果系统中还有active的wakeup source,这个函数将会阻塞,直到系统中所有的wakeup source都release了,这个函数才会返回,返回截至当前系统中已经完成的wakeup source count。

    如果返回true,上面将接着call WriteStringToFd将“mem”写入/sys/power/state执行suspend流程,否则continue调用readFd阻塞调用读取wakeup count系统调用。

    bool pm_get_wakeup_count(unsigned int *count, bool block)
    {
    unsigned int cnt, inpr;
    
    if (block) {
    DEFINE_WAIT(wait);
    
    for (;;) {
    prepare_to_wait(&wakeup_count_wait_queue, &wait,
    TASK_INTERRUPTIBLE); //wait here,挡有wakeup source release时,将wakeup它,即在wakeup_source_deactivate里release一个wakeup source时,将wakeup它
    split_counters(&cnt, &inpr);
    if (inpr == 0 || signal_pending(current)) //如果系统里没有一个in progress wakeup source,break此死循环,read wakeup count阻塞系统调用将返回
    break;
    pm_print_active_wakeup_sources();
    schedule();
    }
    finish_wait(&wakeup_count_wait_queue, &wait);
    }
    
    split_counters(&cnt, &inpr);
    *count = cnt;
    return !inpr;
    }
    bool pm_save_wakeup_count(unsigned int count)
    {
    unsigned int cnt, inpr;
    unsigned long flags;
    
    events_check_enabled = false;
    raw_spin_lock_irqsave(&events_lock, flags);
    split_counters(&cnt, &inpr);
    if (cnt == count && inpr == 0) {
    saved_count = count;
    events_check_enabled = true;
    }
    raw_spin_unlock_irqrestore(&events_lock, flags);
    return events_check_enabled;
    }
  • 相关阅读:
    RE
    【LeetCode】198. House Robber
    【LeetCode】053. Maximum Subarray
    【LeetCode】152. Maximum Product Subarray
    【LeetCode】238.Product of Array Except Self
    【LeetCode】042 Trapping Rain Water
    【LeetCode】011 Container With Most Water
    【LeetCode】004. Median of Two Sorted Arrays
    【LeetCode】454 4Sum II
    【LeetCode】259 3Sum Smaller
  • 原文地址:https://www.cnblogs.com/aspirs/p/15634896.html
Copyright © 2011-2022 走看看