Android低功耗子系统的投票机制以及触发进入系统休眠的过程

  • 从kernel角度看,系统是否进入休眠应该由内核来控制,因此Linux引入了 wakeup source以及autosleep机制

    在内核中,使用wakeup source提供投票机制,让各个系统模块投票是否允许系统进入休眠,当所有的模块都投票允许系统进入休眠时,autosleep机制检测到这一情况,尝试让系统进入休眠。

  • 从Android角度看,系统是否进入休眠应该由上层应用决定,因此Android引入了Wakelocks以及SystemSuspend service

    • 关于wakelocks的介绍,请参考:Wakelocks 框架设计与实现
    • 关于 SystemSuspend Service,可参考:SystemSuspend 服务
      • 代码路径:system/hardware/interfaces/suspend/1.0/default/

      • 该服务创建了两个线程:

        • 主线程:响应来自Client的请求以分配wakelock, 增加/减少 suspend counter
        • 挂起线程:控制系统的休眠,判断系统是否符合进入休眠的条件(在framework中的PowerManagerService.java会根据一些事件,比如息屏亮屏,动态开关autosuspend,从而动态开启/结束该挂起线程)

          挂起线程的实现与autosleep的流程类似(但需要与主线程处理好suspend counter的同步问题),其伪代码可以参考如下:
        c 复制代码
           while (1) {
              do {
                ret = read(&cnt, "/sys/power/wakeup_count"); //一般会阻塞在此处,直到cnt为0
                if (ret) {
                     ret = write(cnt, "/sys/power/wakeup_count");
                } else {
                     countine;
                }
              } while (!ret);
        
              write("mem", "/sys/power/state");
        
              /* goto here after wakeup */
              ......
           }

    在Android应用层面上,使用wakelocks提供投票机制,让各个系统模块投票是否允许系统进入休眠,当所有的模块都投票允许系统进入休眠且PowerManagerService使能autosuspend时,SystemSuspend service中的挂起线程检测到这一情况,会尝试让系统进入休眠。

因Android提供了SystemSuspend service,因此autosleep机制一般不再使用,
但对于纯Linux系统,一般会使用autosleep机制来检测系统是否应尝试进入休眠。

关于Android低功耗子系统的投票机制以及触发进入系统休眠的过程,强烈建议在有此基础概念的基础上,拜读下面的文章,了解这些机制的发展过程,加深对这部分内容的理解:

  1. Linux电源管理(7)_Wakeup events framework
  2. Linux电源管理(8)_Wakeup count功能
  3. Linux电源管理(9)_wakelocks
  4. Linux电源管理(10)_autosleep