在标准Linux中,休眠主要分三个主要的步骤:(1)冻结用户态进程和内核态任务;(2)调用注册的设备的suspend的回调函数,其调用顺序是按照驱动加载时的注册顺序。(3)休眠核心设备和使CPU进入休眠态冻结进程是内核把进程列表中所有的进程的状态都设置为停止,并且保存下所有进程的上下文。
当这些进程被解冻的时候,它们是不知道自己被冻结过的,只是简单的继续执行。
在标准的linux中,休眠主要分为三个步骤: 1.冻结用户进程和内核态进程。2.调用注册设备的suspend回调函数,调用顺序是按照驱动加载的注册顺序。3.休眠核心设备和CPU进入休眠态冻结进程是把进程列表中的所有进程都设置为停止,并保存所有进程的上下文。
Android除了在linux内核原有的休眠唤醒机制的基础上,又增加了三种机制“
Wake_lock :唤醒锁机制
Early_suspend :预暂停机制
Late_resume :迟唤醒机制
* struct early_suspend {
#ifdef
CONFIG_HAS_EARLYSUSPEND
struct list_head link;
//suspend_work_queue链表
int level; //suspend等级
void (*suspend)(struct early_suspend *h); //进入休眠
void (*resume)(struct early_suspend *h); //退出休眠
#endif
};
基本原理:
当启动一个应用程序时,都可以申请一个wake_lock唤醒锁,每当申请成功后都会向内核注册一下(为了通知系统内核有锁被申请)。当应用程序释放wake_lock的时候,就会注销掉原来申请的wake_lock。只要有一个wake_lock没被注销,系统都不会睡下去,但是系统的各个模块可以进入early_suspend。只有当所有的wake_lock注销掉,内核才能真正的进入kernel睡眠。
其实在系统启动时会创建一个主唤醒锁main_wake_lock,该锁是内核初始化并持有的一个WAKE_LOCK_SUSPEND属性的非限时唤醒锁。因此,系统正常工作时,将始终因为该锁被内核持有而无法进入睡眠状态。也就是说在不添加新锁的情况下,只需将main_wake_lock解锁,系统即可进入睡眠状态。
static
int __init wakelocks_init(void)
{
int ret;
int i;
for (i = 0; i <
ARRAY_SIZE(active_wake_locks); i++)
INIT_LIST_HEAD(&active_wake_locks[i]);
#ifdef
CONFIG_WAKELOCK_STAT
wake_lock_init(&deleted_wake_locks,
WAKE_LOCK_SUSPEND,
"deleted_wake_locks");
#endif
wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND,
"main");
wake_lock(&main_wake_lock);
wake_lock_init(&unknown_wakeup,
WAKE_LOCK_SUSPEND, "unknown_wakeups");
wake_lock_init(&suspend_backoff_lock,
WAKE_LOCK_SUSPEND,
"suspend_backoff");
睡眠唤醒机制的基本框架
(转载)
PowerManager类(PowerManager.java)是向上层应用程序提供的接口类,提供了wake_lock机制(睡眠唤醒子系统)的接口(获取唤醒锁合释放)。上层应用通过这个接口,对系统电源状态的监控。
public final class WakeLock {
private final int mFlags;
private final String mTag;
private final String mPackageName;
private final IBindermToken;
private int mCount;
private boolean mRefCounted = true;
private boolean mHeld;
private WorkSource mWorkSource;
private final Runnable mReleaser = new Runnable() {
public void run() {
release();
}
};;
PowerManager类通过IBinder这种Android中特有的通信模式,与PowerManagerService类进行通信。PowerManagerService是PowerManager类中定义的接口的具体实现,并进一步调用Power类来