• 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;
    }
  • 相关阅读:
    准备开始学习XNA
    徐家骏:华为十年感悟
    memcached详解
    sql时间
    Sql server log file 缩小和删除
    看高手都是运用的灵活自如,打算从今天开始学习他!
    什么是内存对齐
    VS 2008 远程调试 与asp.net
    XNA入门的代码注释
    HTML的段落与文字
  • 原文地址:https://www.cnblogs.com/aspirs/p/15634896.html
Copyright © 2020-2023  润新知