linux时间子系统 - 周期性任务
来源:互联网 发布:python 语音处理 编辑:程序博客网 时间:2024/04/29 02:22
如果内核是有生命的话,那么时间就是内核的心脏,控制着内核的脉搏,但是这颗心脏跳动的方式根据硬件的配置会有不同的跳动方式。内核中有大量的需求需要时间的帮助,比如:定时、进程调度、获得时间等等,在内核中时间子系统就是来实现这部分功能的,根据不同的工作模式(periodic和oneshot)会有不同的工作函数来实现周期性任务,具体分为低精度模式和高精度模式。
1. 低精度模式
1.1 tick_handle_periodic
tick_handle_periodic函数的调用图如下:
此函数主要是更新jiffies_64、计算负载、更新墙上时间也就是系统时间,由于是工作在periodic模式,所以每次执行完毕,没必要reprogram下一次的event。
下面再介绍一下update_process_times
1.2 update_process_times
A : 从periodic转换到oneshot模式(动态模式),分为低精度和高精度
B:调度相关操作
C:posix timer相关操作
2. 高精度模式
2.1 高精度周期性任务的注册
在高精度模式下,时钟的轮转都是动态的,所以要执行周期性的任务需要基于动态时钟来模拟周期时钟,高精度时钟是基于hrtimer实现的,所以周期性的任务被初始化为一个hrtimer并被注册。
A : 更换要调用的函数为hrtimer_interrupt
B : 设置周期性的hrtimer
2.2 hrtimer_interrupt
hrtimer_interrupt做的主要工作是:
1.得到此时的time_now
2.运行hrtimer队列中的任务
3.设置下一次中断的时间
__hrtimer_run_queues主要从队列中得到合适的函数来执行
(kernel/time/hrtimer.c)
static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now){ struct hrtimer_clock_base *base = cpu_base->clock_base; unsigned int active = cpu_base->active_bases; for (; active; base++, active >>= 1) { struct timerqueue_node *node; ktime_t basenow; if (!(active & 0x01)) continue; basenow = ktime_add(now, base->offset); while ((node = timerqueue_getnext(&base->active))) {--------------得到下一个hrtimer struct hrtimer *timer; timer = container_of(node, struct hrtimer, node); /* * The immediate goal for using the softexpires is * minimizing wakeups, not running timers at the * earliest interrupt after their soft expiration. * This allows us to avoid using a Priority Search * Tree, which can answer a stabbing querry for * overlapping intervals and instead use the simple * BST we already have. * We don't add extra wakeups by delaying timers that * are right-of a not yet expired timer, because that * timer will have to trigger a wakeup anyway. */ if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) break; __run_hrtimer(cpu_base, base, timer, &basenow);-------------运行hrtimer } }}
不过有一点还没说清楚,hrtimer_interrupt是和tick_handle_periodic一样执行周期任务的,但是从hrtimer_interrupt中只能看到它会调用相关的function,没有看到tick_periodic相关的操作。这是因为在切换到oneshot的时候,已经把相关的hrtimer注册到其中了,具体下节2.2介绍
2.3 tick_setup_sched_timer
在1.2节中对于模式的切换有一个函数没有太多介绍,这个函数就是tick_setup_sched_timer,它的主要工作就是完成执行类似tick_periodic相关操作函数的初始化,把其加入到hrtimer_cpu_base中
( kernel/time/tick-sched.c )
void tick_setup_sched_timer(void){ struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched); ktime_t now = ktime_get(); /* * Emulate tick processing via per-CPU hrtimers: */ hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);--把sched_timer这个hrtimer加入到hrtimer_cpu_base中 ts->sched_timer.function = tick_sched_timer;------------------------周期性调用的函数(类似tick_periodic) /* Get the next period (per cpu) */ hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); /* Offset the tick to avert jiffies_lock contention. */ if (sched_skew_tick) { u64 offset = ktime_to_ns(tick_period) >> 1; do_div(offset, num_possible_cpus()); offset *= smp_processor_id(); hrtimer_add_expires_ns(&ts->sched_timer, offset); } hrtimer_forward(&ts->sched_timer, now, tick_period); hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED); tick_nohz_activate(ts, NOHZ_MODE_HIGHRES);
2.4 tick_sched_timer
static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer){ struct tick_sched *ts = container_of(timer, struct tick_sched, sched_timer); struct pt_regs *regs = get_irq_regs(); ktime_t now = ktime_get(); tick_sched_do_timer(now);----------------------更新jiffies64 /* * Do not call, when we are not in irq context and have * no valid regs pointer */ if (regs) tick_sched_handle(ts, regs); /* No need to reprogram if we are in idle or full dynticks mode */ if (unlikely(ts->tick_stopped)) return HRTIMER_NORESTART; hrtimer_forward(timer, now, tick_period);----- return HRTIMER_RESTART;}
change log
- linux时间子系统 - 周期性任务
- linux时间子系统 - 动态任务
- Linux周期性任务计划
- Linux 周期性任务计划
- Linux中的周期性计划任务
- linux任务计划、周期性任务执行
- Linux--系统周期性计划任务crond
- Linux下的周期性任务cron(任务触发器crontab)
- 【Linux相识相知】任务计划和周期性任务
- 【Linux相识相知】任务计划和周期性任务
- Linux时间子系统
- Linux时间子系统
- Linux时间子系统
- linux-时间子系统
- linux时间子系统
- linux下时间子系统
- linux时间子系统 - hrtimer
- Linux时间子系统
- Hexo_github_blog
- Android中的线性布局
- 【AI每日播报】解读 2016 年十大机器学习算法及其应用
- Spring事务管理中propagation="REQUIRED"
- 文章标题
- linux时间子系统 - 周期性任务
- HTTP代理与防火墙
- Git(GitHub) 007 如何删除一个库
- 剑指offer-----链表中环的入口节点(java版)
- jdbc
- 懒加载的坑
- Canvas之"黑客帝国"
- leetcode oj 166. Fraction to Recurring Decimal 除法
- MFC程序框架