标签:
linaro 发布的内核版本中,提供了一套wakelock接口与google的wakelock接口实现了无缝对接,该套接口共有6个;
struct wake_lock{ struct wakeup_source ws; }; static inline void wake_lock_init(struct wake_lock *lock,int type,const char* name) { wakeup_source_init(&lock->ws,name); } static inline void wake_lock_destroy(struct wake_lock* lock) { wakeup_source_trash(&lock->ws); } static inline void wake_lock(struct wake_lock* lock) { __pm_stay_awake(&lock->ws); } static inline void wake_lock_timeout(struct wake_lock* lock,long timeout) { __pm_stay_awake(&lock->ws); } static inline void wake_unlock(struct wake_lock* lock) { __pm_relax(&lock->ws); } static inline bool wake_lock_active(struct wake_lock* lock) { return lock->ws.active; }
还有一个重要的数据结构需要亮一下,那就是wakeup_source,该数据结构完成wakelock锁的基本控制
/** * struct wakeup_source - Representation of wakeup sources * * @total_time: Total time this wakeup source has been active. * @max_time: Maximum time this wakeup source has been continuously active. * @last_time: Monotonic clock when the wakeup source's was touched last time. * @prevent_sleep_time: Total time this source has been preventing autosleep. * @event_count: Number of signaled wakeup events. * @active_count: Number of times the wakeup sorce was activated. * @relax_count: Number of times the wakeup sorce was deactivated. * @expire_count: Number of times the wakeup source's timeout has expired. * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. * @has_timeout: The wakeup source has been activated with a timeout. */ struct wakeup_source { const char *name; struct list_head entry; spinlock_t lock; struct timer_list timer; unsigned long timer_expires; ktime_t total_time; ktime_t max_time; ktime_t last_time; ktime_t start_prevent_time; ktime_t prevent_sleep_time; unsigned long event_count; unsigned long active_count; unsigned long relax_count; unsigned long expire_count; unsigned long wakeup_count; bool active:1; bool autosleep_enabled:1; };
1)wake_lock_init:实现wakelock锁的初始化,包括名字初始化,添加到wakelock锁的统一控制链表wakeup_sources中;
static inline void wake_lock_init(struct wake_lock *lock,int type,const char* name) { wakeup_source_init(&lock->ws,name); } <pre class="cpp" name="code">static inline void wakeup_source_init(struct wakeup_source *ws, const char *name) { wakeup_source_prepare(ws, name); wakeup_source_add(ws); }
其中wakelock_source_prepare主要完成的是锁的名字的初始化
/** * wakeup_source_prepare - Prepare a new wakeup source for initialization. * @ws: Wakeup source to prepare. * @name: Pointer to the name of the new wakeup source. * * Callers must ensure that the @name string won't be freed when @ws is still in * use. */ void wakeup_source_prepare(struct wakeup_source *ws, const char *name) { if (ws) { memset(ws, 0, sizeof(*ws)); ws->name = name; } } EXPORT_SYMBOL_GPL(wakeup_source_prepare);
而wakeup_source_add则完成的工作比较多,包括自旋锁的初始化,添加到wakelock锁的全局控制链表中,超时timer的初始化等
/** * wakeup_source_add - Add given object to the list of wakeup sources. * @ws: Wakeup source object to add to the list. */ void wakeup_source_add(struct wakeup_source *ws) { if (WARN_ON(!ws)) return; spin_lock_init(&ws->lock); setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws);//pm_wakeup_timer_fn设置为wakelock锁的超时回调,供超时锁使用 ws->active = false; ws->last_time = ktime_get(); spin_lock_irq(&events_lock); list_add_rcu(&ws->entry, &wakeup_sources);//此处添加到链表中,wakelock模块主要操作该链表来控制wakelock锁 spin_unlock_irq(&events_lock); } EXPORT_SYMBOL_GPL(wakeup_source_add);
其中pm_wakeup_timer_fn的实现如下,主要完成wakelock锁的释放,以及相关debug信息的记录
/** * pm_wakeup_timer_fn - Delayed finalization of a wakeup event. * @data: Address of the wakeup source object associated with the event source. * * Call wakeup_source_deactivate() for the wakeup source whose address is stored * in @data if it is currently active and its timer has not been canceled and * the expiration time of the timer is not in future. */ static void pm_wakeup_timer_fn(unsigned long data) { struct wakeup_source *ws = (struct wakeup_source *)data; unsigned long flags; spin_lock_irqsave(&ws->lock, flags); if (ws->active && ws->timer_expires && time_after_eq(jiffies, ws->timer_expires)) { wakeup_source_deactivate(ws); ws->expire_count++; } spin_unlock_irqrestore(&ws->lock, flags); }
2)wake_lock_destroy:该接口完成wakelock锁的销毁操作,其实使用上的地方不多,一般创建完一个wakelock锁都会一直使用的
static inline void wake_lock_destroy(struct wake_lock* lock) { wakeup_source_trash(&lock->ws); } static inline void wakeup_source_trash(struct wakeup_source *ws) { wakeup_source_remove(ws); wakeup_source_drop(ws); }
其中wakeup_source_remove负责把wakelocks锁从控制链表中删除
/** * wakeup_source_remove - Remove given object from the wakeup sources list. * @ws: Wakeup source object to remove from the list. */ void wakeup_source_remove(struct wakeup_source *ws) { if (WARN_ON(!ws)) return; spin_lock_irq(&events_lock); list_del_rcu(&ws->entry); spin_unlock_irq(&events_lock); synchronize_rcu(); }
而wakeup_source_drop则主要负责把对应timer从激活链表中删除(如果是出于激活状态),以及释放wakelock锁,而且该函数注释也提醒了,调用该函数时,一定要确保__pm_stay_awake() or __pm_wakeup_event()两个函数没有并行被调用,否则删除状态未知。
/** * wakeup_source_drop - Prepare a struct wakeup_source object for destruction. * @ws: Wakeup source to prepare for destruction. * * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never * be run in parallel with this function for the same wakeup source object. */ void wakeup_source_drop(struct wakeup_source *ws) { if (!ws) return; del_timer_sync(&ws->timer); __pm_relax(ws); }
3)wake_lock:投票反对睡眠(待完善)
static inline void wake_lock(struct wake_lock* lock) { __pm_stay_awake(&lock->ws); }
4)wake_lock_timeout:投超时锁,超时后释放锁(待完善)
5)wake_unlock:投票同意睡眠,释放wakelock锁(待完善)
6)wake_lock_active:返回锁的激活状态(待完善)
标签:
原文地址:http://blog.csdn.net/lixiaojie1012/article/details/44264583