二 android 休眠唤醒机制分析 — early_suspend( 二 )


[cpp] view plain copyprint ?
(*){(&);(&->link);(&);}(pend);
void unregister_early_suspend(struct early_suspend *handler){mutex_lock(&early_suspend_lock);list_del(&handler->link);mutex_unlock(&early_suspend_lock);}EXPORT_SYMBOL(unregister_early_suspend);
注销流程则只是将节点从链表中移除 。
4、e
前面我们看到用户空间在写/sys/power/state节点的时候会执行e()函数,该函数代码如下:
[cpp] view plain copyprint ?
state(tate){;;(&,);=state&;//打印当前状态if(&){;;(&ts);(ts 。,&tm);("e:%s(%d->%d)at%lld""(%d-d-dd:d:d 。%)\n",!=?"sleep":"",ate,,(()),tm 。+1900,tm 。+1,tm 。,tm 。
,tm 。,tm 。,ts 。);}//如果新状态是休眠状态if(!&&!=){state|=;(" 。\n");//执行缓存同步与浅度休眠的工作队列(,&);(,&);}(&&==){//如果新状态是唤醒状态state&=~;//激活内核锁(&);//执行浅度唤醒的工作队列(,&);}//更新全局状态ate=;re(&,);}
void request_suspend_state(suspend_state_t new_state){unsigned long irqflags;int old_sleep;spin_lock_irqsave(&state_lock, irqflags);old_sleep = state & SUSPEND_REQUESTED;// 打印当前状态if (debug_mask & DEBUG_USER_STATE) {struct timespec ts;struct rtc_time tm;getnstimeofday(&ts);rtc_time_to_tm(ts.tv_sec, &tm);pr_info("request_suspend_state: %s (%d->%d) at %lld ""(%d-d-d d:d:d.%09lu UTC)\n",new_state != PM_SUSPEND_ON ? "sleep" : "wakeup",requested_suspend_state, new_state,ktime_to_ns(ktime_get()),tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);}// 如果新状态是休眠状态if (!old_sleep && new_state != PM_SUSPEND_ON) {state |= SUSPEND_REQUESTED;pr_info("sys_sync_work_queue early_sys_sync_work.\n");// 执行缓存同步与浅度休眠的工作队列queue_work(sys_sync_work_queue, &early_sys_sync_work);queue_work(suspend_work_queue, &early_suspend_work);} else if (old_sleep && new_state == PM_SUSPEND_ON) {// 如果新状态是唤醒状态state &= ~SUSPEND_REQUESTED;// 激活内核锁wake_lock(&main_wake_lock);// 执行浅度唤醒的工作队列queue_work(suspend_work_queue, &late_resume_work);}// 更新全局状态requested_suspend_state = new_state;spin_unlock_irqrestore(&state_lock, irqflags);}
函数首先打印出当前状态变化的log,然后判断新状态,如果是休眠状态则置位标志,然后将同步缓存、浅度休眠工作队列加入相应的内核线程执行;如果新状态是唤醒则首先将激活,然后再将浅度唤醒工作队列加入内核线程执行;最后更新全局状态变量,因为提供了一个内核空间接口用于获取当前休眠唤醒状态:

二  android 休眠唤醒机制分析 — early_suspend

文章插图
[cpp] view plain copyprint ?
//返回系统状态值(void){;}
// 返回系统状态值suspend_state_t get_suspend_state(void){return requested_suspend_state;}
5、、 和
[cpp] view plain copyprint ?
end(*work){*pos;;=0;(&);(&,);if(state==)//判断当前状态是否在请求浅度休眠state|=;//如果是则置位=1;re(&,);if(abort){//取消(&)(":abort,state%d\n",state);(&);;}if(&)(":\n");//遍历浅度休眠链表并执行其中所有函数//执行顺序根据优先等级而定,等级越低越先执行(pos,&rs,link){if(pos->!=NULL)pos->(pos);}(&);if(&)(":sync\n");/*,*///();abort:(&,);if(state==)(&);re(&,);}
static void early_suspend(struct work_struct *work){struct early_suspend *pos;unsigned long irqflags;int abort = 0;mutex_lock(&early_suspend_lock);spin_lock_irqsave(&state_lock, irqflags);if (state == SUSPEND_REQUESTED)// 判断当前状态是否在请求浅度休眠state |= SUSPENDED;// 如果是则置位SUSPENDEDelseabort = 1;spin_unlock_irqrestore(&state_lock, irqflags);if (abort) {// 取消early_suspendif (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: abort, state %d\n", state);mutex_unlock(&early_suspend_lock);goto abort;}if (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: call handlers\n");// 遍历浅度休眠链表并执行其中所有suspend函数// 执行顺序根据优先等级而定,等级越低越先执行list_for_each_entry(pos, &early_suspend_handlers, link) {if (pos->suspend != NULL)pos->suspend(pos);}mutex_unlock(&early_suspend_lock);if (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: sync\n");/* Remove sys_sync from early_suspend, and use work queue to complete sys_sync *///sys_sync();abort:spin_lock_irqsave(&state_lock, irqflags);if (state == SUSPEND_REQUESTED_AND_SUSPENDED)wake_unlock(&main_wake_lock);spin_unlock_irqrestore(&state_lock, irqflags);}