Linux时间子系统之四(2):定时器…
来源:互联网 发布:mac怎么切换大小写 编辑:程序博客网 时间:2024/05/22 14:29
4. tick_device
当内核没有配置成支持高精度定时器时,系统的tick由tick_device产生,tick_device其实是clock_event_device的简单封装,它内嵌了一个clock_event_device指针和它的工作模式:
[cpp] viewplaincopy
- struct
tick_device { -
struct clock_event_device *evtdev; -
enum tick_device_mode mode; - };
[cpp] viewplaincopy
-
- DEFINE_PER_CPU(struct
tick_device, tick_cpu_device);
[cpp] viewplaincopy
- static
int tick_check_new_device( structclock_event_device *newdev) - {
-
...... -
cpu = smp_processor_id(); -
if (!cpumask_test_cpu(cpu, newdev->cpumask)) -
goto out_bc; -
-
td = &per_cpu(tick_cpu_device, cpu); -
curdev = td->evtdev;
[cpp] viewplaincopy
- if
(!cpumask_equal(newdev->cpumask, cpumask_of(cpu))) { -
...... -
if (!irq_can_set_affinity(newdev->irq)) -
goto out_bc; -
...... -
if (curdev && cpumask_equal(curdev->cpumask, cpumask_of(cpu))) -
goto out_bc; - }
反之,如果本cpu已经有了一个clock_event_device,则根据是否支持单触发模式和它的rating值,决定是否替换原来旧的clock_event_device:
在这些判断都通过之后,说明或者来cpu还没有绑定tick_device,或者是新的更好,需要替换:
[cpp] viewplaincopy
- if
(curdev) { -
if ((curdev->features & CLOCK_EVT_FEAT_ONESHOT) && -
!(newdev->features & CLOCK_EVT_FEAT_ONESHOT)) -
goto out_bc; //新的不支持单触发,但旧的支持,所以不能替换 -
if (curdev->rating >= newdev->rating) -
goto out_bc; //旧的比新的精度高,不能替换 - }
[cpp] viewplaincopy
- if
(tick_is_broadcast_device(curdev)) { -
clockevents_shutdown(curdev); -
curdev = NULL; - }
- clockevents_exchange_device(curdev,
newdev); - tick_setup_device(td,
newdev, cpu, cpumask_of(cpu));
上面的tick_setup_device函数负责重新绑定当前cpu的tick_device和新注册的clock_event_device,如果发现是当前cpu第一次注册tick_device,就把它设置为TICKDEV_MODE_PERIODIC模式,如果是替换旧的tick_device,则根据新的tick_device的特性,设置为TICKDEV_MODE_PERIODIC或TICKDEV_MODE_ONESHOT模式。可见,在系统的启动阶段,tick_device是工作在周期触发模式的,直到框架层在合适的时机,才会开启单触发模式,以便支持NO_HZ和HRTIMER。
5. tick事件的处理--最简单的情况
clock_event_device最基本的应用就是实现tick_device,然后给系统定期地产生tick事件,通用时间框架对clock_event_device和tick_device的处理相当复杂,因为涉及配置项:CONFIG_NO_HZ和CONFIG_HIGH_RES_TIMERS的组合,两个配置项就有4种组合,这四种组合的处理都有所不同,所以这里我先只讨论最简单的情况:
- CONFIG_NO_HZ == 0;
- CONFIG_HIGH_RES_TIMERS == 0;
[cpp] viewplaincopy
- if
(td->mode == TICKDEV_MODE_PERIODIC) -
tick_setup_periodic(newdev, 0); - else
-
tick_setup_oneshot(newdev, handler, next_event);
[cpp] viewplaincopy
- void
tick_handle_periodic( structclock_event_device *dev) - {
-
int cpu = smp_processor_id(); -
ktime_t next; -
-
tick_periodic(cpu); -
-
if (dev->mode != CLOCK_EVT_MODE_ONESHOT) -
return; -
-
next = ktime_add(dev->next_event, tick_period); -
for (;;) { -
if (!clockevents_program_event(dev, false))next, -
return; -
if (timekeeping_valid_for_hres()) -
tick_periodic(cpu); -
next = ktime_add(next, tick_period); -
} - }
[cpp] viewplaincopy
- static
void tick_periodic( intcpu) - {
-
if (tick_do_timer_cpu == cpu) { -
write_seqlock(&xtime_lock); -
-
-
tick_next_period = ktime_add(tick_next_period, tick_period); -
-
do_timer(1); -
write_sequnlock(&xtime_lock); -
} -
-
update_process_times(user_mode(get_irq_regs())); -
profile_tick(CPU_PROFILING); - }
- 更新jiffies_64变量;
- 更新墙上时钟;
- 每10个tick,更新一次cpu的负载信息;
- 更新进程的时间统计信息;
- 触发TIMER_SOFTIRQ软件中断,以便系统处理传统的低分辨率定时器;
- 检查rcu的callback;
- 通过scheduler_tick触发调度系统进行进程统计和调度工作;
- Linux时间子系统之四(2):定时器…
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device .
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之四:定时器的引擎:clock_event_device
- Linux时间子系统之(四):timekeeping
- Linux时间子系统之(四):timekeeping
- 对Linux内核中进程上下文和中断上…
- Linux输入子系统-数据结构关系
- 对输入子系统分析总结
- 输入子系统读书笔记 input
- Visual studio 2008l连接oracle 10g
- Linux时间子系统之四(2):定时器…
- ASM创建目录备份METADATA
- SIP协议解析与实现
- ActiveMQ中数据表SQL的管理
- 最近打算写几个专利
- 在 Visual Studio 中调试 MSBuild 脚本
- 后可视化编程时代
- Spring面试题之神奇的scope的作用域
- ANDROID SDK体系介绍