关于wake_lock
在上文中,已经介绍了wakelock机制,下面从代码的角度进行介绍。
wakelock有2种类型,常用为WAKE_LOCK_SUSPEND,作用是防止系统进入睡眠。WAKE_LOCK_IDLE
这种锁不会影响到系统进入休眠,但是如果这种锁被持有,那么系统将无法进入idle空闲模式。
enum
WAKE_LOCK_SUSPEND,
WAKE_LOCK_IDLE,
WAKE_LOCK_TYPE_COUNT
};
Wakelock有加锁和解锁2种操作,加锁有2种方式,第一种是永久加锁(wake_lock),这种锁必须手动的解锁;另一种是超时锁(wake_lock_timeout),这种锁在过去指定时间后,会自动解锁。
void
{
wake_lock_internal(lock,
}
void
{
wake_lock_internal(lock,
}
对于wakelock,timeout
static
struct
{
int
unsigned
long
spin_lock_irqsave(&list_lock,
type
BUG_ON(type
BUG_ON(!(lock->flags
#ifdef
if
if
pr_info("wakeup
wait_for_wakeup
lock->stat.wakeup_count++;
}
if
wake_unlock_stat_locked(lock,
lock->stat.last_time
}
#endif
if
lock->flags
#ifdef
lock->stat.last_time
#endif
}
list_del(&lock->link);
if
if
pr_info("wake_lock:
lock->name,
(timeout
lock->expires
lock->flags
list_add_tail(&lock->link,
}
if
pr_info("wake_lock:
lock->expires
lock->flags
list_add(&lock->link,
}
if
current_event_num++;
#ifdef
if
update_sleep_wait_stats_locked(1);
else
update_sleep_wait_stats_locked(0);
#endif
if
expire_in
else
expire_in
if
if
pr_info("wake_lock:
"%ld\n",
mod_timer(&expire_timer,
}
if
if
pr_info("wake_lock:
lock->name);
if
queue_work(suspend_work_queue,
}
}
spin_unlock_irqrestore(&list_lock,
}
而对于wake_lock_timeout,在经过timeout时间后,才加锁。再判断当前持有wakelock时,启动另一个定时器,在expire_timer的回调函数中再次判断是否持有wakelock。
static
{
long
unsigned
if
pr_info("expire_wake_locks:
spin_lock_irqsave(&list_lock,
if
print_active_locks(WAKE_LOCK_SUSPEND);
has_lock
if
pr_info("expire_wake_locks:
if
queue_work(suspend_work_queue,
spin_unlock_irqrestore(&list_lock,
}
static
在wakelock中,有2个地方可以让系统从early_suspend进入suspend状态。分别是:
l
l