内核中有大量的函数都是基于时间驱动的。
像对调度程序中的运行队列进行平衡调整
系统定时器是一种可编程硬件芯片,它能以固定频率产生中断,它所对应的中断处理程序负责更新系统时间,也负责执行需要周期性运行的任务。
系统定时器和时钟中断处理程序是Linux系统内核管理机制中的中枢。
系统定时器以某种频率自行触发时钟中断,该频率可以通过编程预定,称作节拍率(tick rate)。
墙上时间(实际时间)、
内核通过控制时钟中断维护实际时间,内核提供一组系统调用以获取实际日期和实际时间。
系统运行时间
利用时间中断周期执行的工作:
1. 更新系统运行时间和实际时间;
2. smp上均衡调度程序中各处理器上的运行队列;
3. 检查当前进行时间片,调度;
4. 运行超时的动态定时器;
5. 更新资源消耗和处理器时间的统计值;
节拍率,内核在<asm/param.h>文件中定义了这个值。
依赖定时值执行的系统调用,比如poll()和select()
全局变量jiffies用来记录自系统启动以来产生的节拍的总数。
jiffies定义于文件<linux/jiffies.h>中
内核本身很少用到绝对时间,时钟转化为秒经常会用在内核和用户空间进行交互的时候
ld(1)脚本用于连接主内核映像(arch/x86/kernel/vmlinux.lds.S)
通过user_tick区别是花费在用户空间还是内核空间
user_tick的值是通过查看系统寄存器来设置的
user_mode(get_irq_regs())
内核对进程进行时间计数时,是根据中断发生时处理器所处的模式进行分类统计的
从用户空间取得墙上时间的主要接口是gettimeofday(),在内核中对应系统调用为sys_gettimeofday()
下半部的本意并非是放到以后的某个时间去执行任务,而仅仅是不在当前时间执行
定时器由结构timer_list表示,定义在文件<linux/timer.h>中
init_timer(&my_timer)
add_timer(&my_timer)
del_timer(&my_timer)
时钟中断处理程序会执行update_process_times()函数,该函数随机调用run_local_timers()函数
run_local_timers中调用run_timer_softirq()函数,它处理软中断TIMER_SOFTIRQ,从而在当前处理器上运行所有超时定时器。
使用schedule_timeout()函数,会让需要延迟执行的任务睡眠到指定的延迟时间耗尽后再重新运行。该方法不能保证睡眠时间正好等于指定的延迟时间,只能尽量使睡眠时间接近指定的延迟时间。
当指定的时间到期后,内核唤醒被延迟的任务并将其重新放回运行队列。
set_current_state(TASK_INTERRUPTIBLE)
schedule_timeout(s*HZ)