凡是
linux
核心上層關機時,底層均會調到
kernel_power_off(),
電腦可以使用按鍵
ctr+alt+del
鍵進入關機,下面我們看看**流程:
syscall_define4() -> kernel_power_off
()-> pm_power_off_prepare() -> machine_power_off()-> pm_power_off()
在這裡我想說的是pm_power_off_prepare()
和pm_power_off()
都是與平台相關,有些平台只有填充
pm_power_off
而pm_power_off_prepare
並沒有填充。而在
pm_power_off
()函式中一般函式不能被呼叫因為整個
syscore
已經關閉,系統不能呼叫
idle thread
。所以關機前我們通常在
pm_power_off_prepare
()函式來實現,關機前通常很有可能需要完成的其他事,我們在這裡就可以填充。
* function pointers to optional machine specific functions
void (*pm_power_off)(void);
export_symbol(pm_power_off);
* if set, this is used for preparing the system to power off.
void (*pm_power_off_prepare)(void);
例如我們在高通平台所加的:
在arch/arm/mach-msm/restart.c
static int __init msm_restart_init(void)
pm_power_off = msm_power_off;
pm_power_off_prepare = msm_power_off_prepare;
源**:
kernel/sys.c
syscall_define4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
char buffer[256];
int ret = 0;
/* we only trust the superuser with rebooting the system. */
if (!capable(cap_sys_boot))
return -eperm;
/* for safety, we require "magic" arguments. */
if (magic1 != linux_reboot_magic1 ||
(magic2 != linux_reboot_magic2 &&
magic2 != linux_reboot_magic2a &&
magic2 != linux_reboot_magic2b &&
magic2 != linux_reboot_magic2c))
return -einval;
/* instead of trying to make the power_off code look like
* halt when pm_power_off is not set do it the easy way.
if ((cmd == linux_reboot_cmd_power_off) && !pm_power_off)
cmd = linux_reboot_cmd_halt;
mutex_lock(&reboot_mutex);
switch (cmd) {
case linux_reboot_cmd_restart:
kernel_restart(null);
break;
case linux_reboot_cmd_cad_on:
c_a_d = 1;
break;
case linux_reboot_cmd_cad_off:
c_a_d = 0;
break;
case linux_reboot_cmd_halt:
kernel_halt();
do_exit(0);
panic("cannot halt");
case linux_reboot_cmd_power_off:
kernel_power_off();
do_exit(0);
break;
case linux_reboot_cmd_restart2:
if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
ret = -efault;
break;
buffer[sizeof(buffer) - 1] = '\0';
kernel_restart(buffer);
break;
#ifdef config_kexec
case linux_reboot_cmd_kexec:
ret = kernel_kexec();
break;
#endif
#ifdef config_hibernation
case linux_reboot_cmd_sw_suspend:
ret = hibernate();
break;
#endif
default:
ret = -einval;
break;
mutex_unlock(&reboot_mutex);
return ret;
void kernel_power_off(void)
kernel_shutdown_prepare(system_power_off);
if (pm_power_off_prepare)
pm_power_off_prepare();
disable_nonboot_cpus();
syscore_shutdown();
printk(kern_emerg "power down.\n");
kmsg_dump(kmsg_dump_poweroff);
machine_power_off();
void machine_power_off(void)
machine_shutdown();
if (pm_power_off)
pm_power_off();
網路流 費用流
這個好像不考 沒事可以騙分 費用流,顧名思義,就是有費用的流,也就是說,給乙個網路流圖中的每條弧增加乙個單位流量費用。一般來說求解的費用流都是最大流最小費用。好像沒什麼好bb的 這裡推薦使用zkw演算法求解最小費用流,看著 理解就行,應該還是很好理解的。zkw演算法在稠密圖上跑得飛快,在稀疏圖上還不...
IO流 記憶體流
記憶體流 bytearrayinputstream bytearrayoutputstream chararrayinputstream charoutputstream stringreader stringwriter 目的 將資料臨時存放在陣列中 相當於記憶體中 tips 上面的writer ...
網路流 費用流
網路流有很多種類 其中最大流 有增廣路演算法和預流推進演算法。增廣路演算法就是不斷的新增增廣路。其中的dinic演算法。會稍微提到isap演算法 poj1273 首先想到dfs一直往後延伸,然後從源點到匯點計算每條路,但是這樣只是單條路的最值,有時可能因為走一條路而間接的認定了除這條路以外的某個路通...