Linux中_countof函数,Linux电源管理(8)_Wakeup count功能

本文详细介绍了Linux电源管理中wakeup count的功能和实现逻辑,其作为Wakeup events framework的一部分,解决系统suspend和wakeup事件同步问题。在suspend过程中,通过读写wakeup count,确保在没有未处理的wakeup事件时才能进行电源状态切换。文章通过代码分析和实际例子阐述了wakeup count如何避免在电源切换时丢失事件处理。
摘要由CSDN通过智能技术生成

Linux电源管理(8)_Wakeup count功能

作者:wowo 发布于:2014-9-12 23:35

分类:电源管理子系统

1. 前言

Wakeup count是Wakeup events framework的组成部分,用于解决“system suspend和system wakeup events之间的同步问题”。本文将结合“Linux电源管理(6)_Generic PM之Suspend功能”和“Linux电源管理(7)_Wakeup events framework”两篇文章,分析wakeup count的功能、实现逻辑、背后的思考,同时也是对这两篇文章的复习和总结。

2. wakeup count在电源管理中的位置

wakeup count的实现位于wakeup events framework中(drivers/base/power/wakeup.c),主要为两个模块提供接口:通过PM core向用户空间提供sysfs接口;直接向autosleep(请参考下一篇文章)提供接口。

71fd7aca4443bcb80fdba9c0b5f5f02d.gif

3. wakeup count的功能

wakeup count的功能是suspend同步,实现思路是这样的:

1)任何想发起电源状态切换的实体(可以是用户空间电源管理进程,也可以是内核线程,简称C),在发起状态切换前,读取系统的wakeup counts(该值记录了当前的wakeup event总数),并将读取的counts告知wakeup events framework。

2)wakeup events framework记录该counts到一个全局变量中(saved_count)。

3)随后C发起电源状态切换(如STR),执行suspend过程。

4)在suspend的过程中,wakeup events framework照旧工作(直到系统中断被关闭),上报wakeup events,增加wakeup events counts。

5)suspend执行的一些时间点(可参考“Linux电源管理(6)_Generic PM之Suspend功能”),会调用wakeup  events framework提供的接口(pm_wakeup_pending),检查是否有wakeup没有处理。

6)检查逻辑很简单,就是比较当前的wakeup counts和saved wakeup counts(C发起电源状态切换时的counts),如果不同,就要终止suspend过程。

4. wakeup count的实现逻辑

4.1 一个例子

在进行代码分析之前,我们先用伪代码的形式,写出一个利用wakeup count进行suspend操作的例子,然后基于该例子,分析相关的实现。

1: do {

2: ret = read(&cnt, "/sys/power/wakeup_count");

3: if (ret) {

4: ret = write(cnt, "/sys/power/wakeup_count");

5: } else {

6: countine;

7: }

8: } while (!ret);

9:

10: write("mem", "/sys/power/state");

11:

12: /* goto here after wakeup */

例子很简单:

a)读取wakeup count值,如果成功,将读取的值回写。否则说明有正在处理的wakeup events,continue。

b)回写后,判断返回值是否成功,如果不成功(说明读、写的过程中产生了wakeup events),继续读、写,直到成功。成功后,可以触发电源状态切换。

4.2 /sys/power/wakeup_count

wakeup_count文件是在kernel/power/main.c中,利用power_attr注册的,如下(大家可以仔细研读一下那一大段注释,内核很多注释写的非常好,而好的注释,就是软件功力的体现):

1: /*

2: * The 'wakeup_count' attribute, along with the functions defined in

3: * drivers/base/power/wakeup.c, provides a means by which wakeup events can be

4: * handled in a non-racy way.

5: *

6: * If a wakeup event occurs when the system is in a sleep state, it simply is

7: * woken up. In turn, if an event that would wake the system up from a sleep

8: * state occurs when it is undergoing a transition to that sleep state, the

9: * transition should be aborted. Moreover, if such an event occurs when the

10: * system is in the working state, an attempt to start a transition to the

11: * given sleep state should fail during certain period after the detection of

12: * the event. Using the 'state' attribute alone is not sufficient to satisfy

13: * these requirements, because a wakeup event may occur exactly when 'state'

14: * is being written to and may be delivered to user space right before it is

15: * frozen, so the event will remain only partially processed until the system is

16: * woken up by another event. In particular, it won't cause the transition to

17: * a sleep state to be aborted.

18: *

19: * This difficulty may be overcome if user space uses 'wakeup_count' before

20: * writing to 'state'. It first should read from 'wakeup_count' and store

21: * the read value. Then, after carrying out its own preparations for the system

22: * transition to a sleep state, it should write the stored value to

23: * 'wakeup_count'. If that fails, at least one wakeup event has occurred since

24: * 'wakeup_count' was read and 'state' should not be written to. Otherwise, it

25: * is allowed to write to &#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值