Something about software suspend (swsusp)

from: http://blog.chinaunix.net/uid-20585891-id-1919736.html

Something about software suspend (swsusp)

What is swsusp(sofeware suspend)?

swsusp (Software Suspend) is a suspend-to-disk implementation in the 2.6 series Linux kernel. It is the Linux equivalent of Windowshibernate functionality. To be simple, Software suspend is the ability to freeze the kernel state and dump it on disk, then restore it upon resuming. This allows to completely stop a computer for a long period while keeping an internal session opened.

Open swsusp feature

To enable swsusp, the following should be selected during kernel configuration:

Power management options → <*>Power management support (CONFIG_PM)

Power management options → <*>Software Suspend (CONFIG_SOFTWARE_SUSPEND)

Power management options → [/dev/resume_partition]Default resume partition (CONFIG_PM_STD_PARTITION)

Do swsusp

. mount sysfs

 # mkdir /sys

 # mount -t sysfs none /sys

. enable flash as swap

  # mkswap /dev/mtdblock3

  # swapon /dev/mtdblock3

. trigger suspend to disk

  # echo disk > /sys/power/state

After the suspend to disk is triggered, messages are emitted to console, and machine would halt.

On next bootup of the board, pass below additional argument to kernel:

resume=/dev/mtdblock3

Below is an example:

#setenv bootargs console=ttyS0,115200n8 ip=dhcp root=/dev/nfs resume=/dev/mtdblock3

# saveenv

 

Implement swsusp(s2disk)

Suspend procedure

The suspend procedure is shown below:

1. Trigger

Suspend procedure is triggered from writing disk to /sys/power/state operation. The call stack to the entrance of the suspend procedure is shown as below.

sys_write()

+-vfs_write()

+-sysfs_write_file()

+-flush_write_buffer()

+-subsys_attr_store()

+-state_store()

+-enter_state()

+-pm_suspend_disk()

suspend

2. Freeze processes

This is done by calling the freeze_processes() procedure. It freezes user processes, and then freezes kernel tasks.

3. Free unnecessary memory

This is done by calling the free_some_memory() procedure. It calls shrink_all_memory() inside.

4. Suspend devices

This is done by calling the device_suspend() procedure. It calls suspend_device() and then the suspend() method for all listed active devices.

5. Power down devices

This is done by calling the device_power_down() procedure. It calls suspend_device() to for all listed power off devices.

6. Save processor state

This is done by calling the save_processor_state() procedure. It will save registers other than generic ones, such as segment registers, co-processor registers, and so on.

7. Save processor registers

This is done by calling the swsusp_arch_suspend() procedure. It will save general registers. This is written in assembly language, since the stack may not be used.

8. Allocate memory for snapshot image

This is done by calling the swsusp_alloc() procedure. Page directories get allocated by calling __get_free_pages(), and pages for the image itself gets allocated byget_zeroes_page() for each page directory entry.

9. Copy memory contents to allocated area

This is done by calling the copy_data_pages() procedure. It calls memcpy() for each page to copy.

10. Restore processor state

This is done by calling the restore_processor_state() procedure in swsusp_suspend(). This

is where the software suspend resume procedure comes back. It restores the previously saved processor state.

11. Power up devices

This is done by calling the device_power_up() procedure. It resumes system devices and all listed power off device.

12. Resume devices

This is done by calling the device_resume() procedure. It resumes devices in power off device list.

13. Write page, pagedir, header image to swap

Now that the devices are active, write to swap could be performed. This is done by calling the write_suspend_image() procedure. It writes image data, page directories, and then image header into swap.

14. Power down devices

This is done by calling the device_shutdown() procedure. It calls the shutdown() method for each device. Then, the system device is shutdown.

15. Halt machine

This is done by calling the machine_power_off() procedure. It calls pm_power_off() and the machine halts.

 

Resume procedure

The resume procedure is shown below:

1. Start resume

Resume starts by calling the software_resume() procedure in do_initcalls(), at late_initcall

timing.

2. Check kernel parameter

In software_resume(), it checks for the kernel command line for the resume swap device.

3. Check signature and header of snapshot image

This is done by calling the check_sig() and check_header() procedures. It checks swap image signature for snapshot image, and that the header for the kernel used for suspend and resume is the same.

4. Allocate memory space for snapshot image

5. Read page directory into allocated memory

This is done by calling the read_pagedir() procedure. It allocates page directory memory space by using __get_free_pages() and reads page directory information withbio_read_page().

6. Relocate page directory (if necessary)

7. Read swap image into allocated memory

This is done by calling the data_read() procedure. The page directory area gets relocated if it collides with the snapshot image. Then the snapshot image is read from swap with bio_read_page().

8. Prepare resume

9. Freeze process

10. Free unnecessary memory

11. Suspend devices

These steps are taken to accomplish consistency between suspend and resume, and in case resume fails. These steps are same as Steps 2 to 4 of the suspend procedure.

12. Power down devices

This step is taken to accomplish consistency between suspend and resume. This step is same as Step 5 of the suspend procedure.

13. Save processor state

These steps are taken in case resume fails. These steps are same as Step 6 of the suspend procedure.

14. Copy snapshot image in allocated memory to its original address

15. Restore processor registers

This is done by calling the swsusp_arch_resume() procedure. It copies all image pages from the allocated memory address to its original memory address. It also restores general purpose registers. Since registers are restored, the return address used by this function would be the same as the one in effect for the swsusp_arch_suspend()procedure call at suspend time.

16. Restore processor state

17. Power up devices

This is exactly the same as Steps 10 to 11 of the suspend procedure.

18. Free memory allocated for image

This is done by calling the free_image_pages() procedure. It does free_page() for all pages in image. Page directories are also freed.

19. Resume devices

This is done by calling the device_resume() procedure. The process is the same as Step 12 of the suspend procedure.

20. Thaw processes

This is done by calling the thaw_processes() procedure. This wakes up every thread by calling the wake_up_process() procedure.

 


 

The corresponding block diagrams are draw as below:


References:

[1] Suspend To Disk For ARM http://elinux.org/Suspend_To_Disk_For_ARM

[2] Software-suspend-linux-mini-HOWTO

  http://fchabaud.free.fr/English/Tricks/Laptop/Swsusp/Doc/Software-suspend.html

[3] Software suspend feature http://at-mirror.tuxonice.net/features

[4] µswsusp http://suspend.sourceforge.net/intro.shtml

[5] Improving Linux Startup Time Using Software Resume and other techniques.pdf

### 关于HarmonyOS中Suspend的概念与用法 在HarmonyOS系统中,`suspend` 是一种线程状态,表示线程处于阻塞挂起的状态。这种状态下,线程不会占用CPU资源,直到特定条件满足或者被显式唤醒为止[^3]。 #### Suspend的具体含义 当提到 `suspend` 时,通常指的是线程由于某些原因而进入的一种被动等待状态。例如,在多任务环境中,如果某个线程正在等待某种同步机制(如锁、事件或信号量),它可能会进入 `pend` 或者 `suspend` 状态。具体来说: - **Pend**: 表示线程因请求锁、事件或其他同步对象未成功而导致的阻塞。 - **Suspend**: 主动挂起线程执行,通常是通过API调用来实现的。 - **Delay**: 延迟一段时间后再继续执行。 - **PendTime**: 类似于 `pend`,但带有超时机制。 这些状态都属于线程的阻塞态,意味着它们暂时无法参与调度。 #### 在后台任务中的应用 对于后台任务开发而言,合理管理线程生命周期非常重要。特别是在涉及长时间运行的任务(比如音乐播放器)时,开发者可以利用 HarmonyOS 提供的相关功能来优化性能并减少不必要的资源消耗。例如,应用程序可以通过 `setAVPlaybackState` 将其音频播放状态通知给系统,从而让系统更好地协调前台和后台活动之间的切换[^2]。 另外需要注意的是,在 Stage 模型下,虽然 ServiceExtensionAbility 不允许直接由第三方调用,但是仍然存在其他方式用于构建后台服务逻辑[^4]。这表明即使不能直接操作某些受限组件,也可以借助官方推荐的方法完成类似的功能需求。 以下是关于如何处理线程暂停的一个简单例子: ```java // Java 示例:模拟线程挂起恢复过程 public class ThreadExample { public static void main(String[] args) throws InterruptedException { MyThread myThread = new MyThread(); // 启动线程 myThread.start(); // 让主线程休眠一秒再尝试停止子线程 Thread.sleep(1000); System.out.println("Main thread suspending child..."); myThread.suspend(); // 继续等待两秒后重新激活子线程 Thread.sleep(2000); System.out.println("Main thread resuming child..."); myThread.resume(); } } class MyThread extends Thread { @Override public void run() { int count = 0; while (true){ synchronized(this){ try{ notifyAll(); wait(); }catch(Exception e){} System.out.println(++count+" times running."); } } } public void suspend(){ interrupt(); // 中断线程使其退出循环体外层判断部分 } public void resume(){ synchronized(this){ this.notify(); // 唤醒此实例上的单个线程 } } } ``` 上述代码片段展示了基本的线程控制技巧,尽管实际项目里可能更倾向于采用现代并发库而非原始方法来进行此类操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值