-
从kernel角度看,系统是否进入休眠应该由内核来控制,因此Linux引入了 wakeup source以及autosleep机制
- 关于wakeup source的介绍,请参考: Wakeup Source框架设计与实现
- 关于autosleep机制,请参考: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的同步问题),其伪代码可以参考如下:
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低功耗子系统的投票机制以及触发进入系统休眠的过程,强烈建议在有此基础概念的基础上,拜读下面的文章,了解这些机制的发展过程,加深对这部分内容的理解:
- Linux电源管理(7)_Wakeup events framework
- Linux电源管理(8)_Wakeup count功能
- Linux电源管理(9)_wakelocks
- Linux电源管理(10)_autosleep