linux 中高精度timer的实现-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

相关结构体

每个cpu上绑定一个hrtimer_cpu_base结构体它的active_bases用位记录了有哪些种类的timer对应每种类型的计时器红黑树hrtimer_clock_base在hrtimer_cpu_base>clock_base[]上。

软硬超时调试时机

软超时处理线程的调度时机有两个一个是在硬中断中顺带触发另一个是在每个时间片调度时通过run_local_timers来触发。

硬超时处理线程的调度时机是在hrtimer_reprogram和hrtimer_force_reprogram中设置到硬件上的具体实现是通过tick_program_event设置到硬件上计时器的触发有一次触发(CLOCK_EVT_STATE_ONESHOT)与周期性触发(CLOCK_EVT_STATE_PERIODIC)两种模式一般是单次触发再底层调用clockevents_program_event来配置硬件dev->set_next_ktime设置是时间还是时长由dev->features上有没有CLOCK_EVT_FEAT_KTIME来决定。

软超时的处理

软超时处理的入口是hrtimer_run_softirq这个线程中会找到达到了软超时的task__hrtimer_run_queues判断它没有disable(tasklet_struct->count==)且处于TASKLET_STATE_SCHED的task软超时的任务__run_hrtimer执行它的func或callback并更新下一个即将到达的软超时时间。

硬超时的处理

硬超时是在超时hrtimer_interrupt到来时就直接在中断中处理的。

当时间到达时触发hrtimer_interrupt如果超过了软中断时间将唤醒软中断处理线程然后调用__hrtimer_run_queues找到硬超时的active 的 clock红黑树中所有硬超时的计时器执行__run_hrtimer它实际会从对应红黑树移除timer触发绑定的函数timer->function(timer)这个绑定函数的返回值表示是否需要将计时器更新后重加回红黑树中红黑树操作函数为timerqueue_add和timerqueue_del。调用hrtimer_update_next_event更新距离下次最早的软硬中断的等待时长如果下一个时间点已经过了虚拟机中运行或是callback过长将有可能导致硬中断处理太久则尝试设置一个最小延时时长并设置hang_detected标记以防不断触发hrtimer_interrupt最多尝试三次。

超时时间的设置

用户可以设置到期时间和宽限期schedule_hrtimeout_range_clock记录在timer->_softexpires和timer->node.expires上在达到_softexpires时会在软超时处理线程中专门处理。如果达到expires这个线程还没有处理就在此时触发的硬超时里直接处理了。

注册定时器的接口是hrtimer_start_range_ns如果是一个已经注册过的timer会先把它从红黑树里取出来并重新计算下一个触发的timer可能是软计时也可能硬计时更新到计时器硬件上remove_hrtimer。当没有下一个计时器时超时时间是KTIME_MAX。更新timer的时长后再插入回计时队列enqueue_hrtimer如果发现它还是第一个计时器则重新计算下一个触发的timer来将它的时间更新在计时器硬件上。

这里发现如果它真得是第一个计时器则移除队列与加入队列后都有一个更新计时器硬件的过程这两个过程是可以合并的在remove_hrtimer上有一个reprogram参数把它置为false就可以了。但有个例外情况就是计时器在其它cpu上。

另外实时任务的软硬超时时间是一样的。

纳秒睡眠的实现

系统调用nanosleep(struct old_timespec32 __user *, rqtp, struct old_timespec32 __user *, rmtp) 中rqtp表示请求睡眠时间rmtp表示剩余睡眠时间当在指定的睡眠时间内被信号中断则rmtp指向一个__kernel_timespec结构体该结构体包含睡眠剩余时间的信息以便调用者可以知道剩余的睡眠时间。如果不关心剩余的睡眠时间可以将rmtp设置为NULL。

实现中调用hrtimer_nanosleep核心在do_nanosleep在hrtimer_sleeper_start_expires中将timer设置上注册的回调是hrtimer_wakeup。然后调用schedule提交当前线程如果是内核中任务的话并调度下一task。当调度回来时删除timerhrtimer_cancel如果是超时唤醒的则在hrtimer_wakeup中已将t->task为空正常返回。如果是中断唤醒的则do_nanosleep返回ERESTART_RESTARTBLOCK它会使current->restart_block->fn 设置为hrtimer_nanosleep_restart并更新超时时间这样如果是用户调用的nanosleep则在返回用户空间前会自动重新调nanosleep。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux

“linux 中高精度timer的实现-CSDN博客” 的相关文章

Linux下命令(2)1年前 (2023-02-02)
Linux下更新curl版本1年前 (2023-02-02)
Linux 发布 JavaWeb 项目1年前 (2023-02-02)
Linux面试题1年前 (2023-02-02)
Linux下安装Mysql8.0.111年前 (2023-02-02)
从零开始学习Linux1年前 (2023-02-02)
Linux三剑客之Sed1年前 (2023-02-02)
Linux FHS结构1年前 (2023-02-02)