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;
    }
  • 相关阅读:
    招聘测试开发二三事
    首次曝光:大厂都是这样过1024的,看的我酸了
    1024程序员节:今天,我们不加班!
    TesterHome创始人思寒:如何从手工测试进阶自动化测试?十余年经验分享
    ASP.NET网站中设置404自定义错误页面
    IIS 7 应用程序池自动回收关闭的解决方案
    ASP.NET项目中引用全局dll
    ASP.NET WebForm中前台代码如何绑定后台变量
    Git使用过程中出现项目文件无法签入Source Control的情况
    ASP.NET中身份验证的三种方法
  • 原文地址:https://www.cnblogs.com/aspirs/p/15634896.html
Copyright © 2011-2022 走看看