linux时间子系统(三)

原创 2018年04月17日 17:32:40

2.2.3 timekeeper初始化 

void __init timekeeping_init(void)

{

        struct clocksource *clock;

        unsigned long flags;

        struct timespec now, boot;

 

        read_persistent_clock(&now);

        read_boot_clock(&boot);

 

        raw_spin_lock_irqsave(&xtime_lock, flags);

        write_seqcount_begin(&xtime_seq);

 

        ntp_init();

 

        clock = clocksource_default_clock();

        if (clock->enable)

                clock->enable(clock);

        timekeeper_setup_internals(clock);

 

        xtime.tv_sec = now.tv_sec;

        xtime.tv_nsec = now.tv_nsec;

        raw_time.tv_sec = 0;

        raw_time.tv_nsec = 0;

        if (boot.tv_sec == 0 && boot.tv_nsec == 0) {

                boot.tv_sec = xtime.tv_sec;

                boot.tv_nsec = xtime.tv_nsec;

        }

        set_normalized_timespec(&wall_to_monotonic,

                                -boot.tv_sec, -boot.tv_nsec);

        total_sleep_time.tv_sec = 0;

        total_sleep_time.tv_nsec = 0;

        write_seqcount_end(&xtime_seq);

        raw_spin_unlock_irqrestore(&xtime_lock, flags);

}

   从初始化函数中可以看到,内核首先通过read_persistent_clock函数,从RTC硬件中获取RTC time。如果不存在RTC硬件,则RTC time被初始化为0。之后,初始化xtime,raw_time,wall_to_monotonic和total_sleep_time。

2.2.4 时间更新 

2.2.4.1 xtime和raw_time更新 

static void timekeeping_forward_now(void)

{

        cycle_t cycle_now, cycle_delta;

        struct clocksource *clock;

        s64 nsec;

 

        clock = timekeeper.clock;

        cycle_now = clock->read(clock);

        cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;

        clock->cycle_last = cycle_now;

 

        nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult,

                                  timekeeper.shift);

 

        /* If arch requires, add in gettimeoffset() */

        nsec += arch_gettimeoffset();

 

        timespec_add_ns(&xtime, nsec);

 

        nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);

        timespec_add_ns(&raw_time, nsec);

} 

  在本函数中,首先计算当前时刻与上一次调用read回调函数时刻clocksoure计数值的差值,记为cycle_delta。之后,在计算xtime的调整时长时,使用的是timekeeper结构中的mult和shift字段,而在计算raw_time的调整时长时,使用的是clocksource的mult和shift字段。因timekeeper的mult字段会被ntp调整,所以说xtime受ntp调整的影响而raw_time不受ntp调整的影响。

2.2.4.2 total_sleep_time/monotonic time

static void __timekeeping_inject_sleeptime(struct timespec *delta)

{

        xtime = timespec_add(xtime, *delta);

        wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta);

        total_sleep_time = timespec_add(total_sleep_time, *delta);

}

   在休眠结束时会调用__timekeeping_inject_sleeptime来调整时间。由于xtime是墙上时间,所以必须加上休眠时间。monotonic time不受休眠时间的影响,所以需要在wall_to_monotonic中减去相应的休眠时间,这样xtime与wall_to_monotonic的和所表示的monotonic time的值就没有发生跳变。在最后,更新total_sleep_time的值。

  由于monotonic time的值是xtime与wall_to_monotonic之和,所以除了休眠时间和使用do_settimeofday调整时间时需要调整wall_to_monotonic外,其他时候,monotonic time随xtime增长而增长。所以大部分时间我们不需要调整wall_to_monotonic变量的值。


Linux时间子系统.pdf

  • 2017年12月11日 22:43
  • 10.09MB
  • 下载

Linux时间子系统(一) -- 原理

转载请标明出处floater的csdn blog,http://blog.csdn.net/flaoter1 内核概述内核2.6之前的时间子系统主要是围绕低分辨定时器和基于它实现的tick时钟周期展开...
  • flaoter
  • flaoter
  • 2017-08-19 16:34:18
  • 508

linux下时间子系统

每个architecture相关的代码中要有实现clock event会让clock source模块。 一般而言,每个CPU形成自己的一个小系统,有自己的调度,有自己的进程统计,这个小系统都是拥有自...
  • Destihang
  • Destihang
  • 2016-03-29 21:34:52
  • 429

LINUX邻居子系统(一)

邻居子系统是linux网络协议栈中非常庞大的一块,也是比较混乱复杂的一块,不过有一点感觉挺好玩的就是 它不涉及太多具体协议的内容,所以阅读起来还不算太复杂 而且它很多时候自成一个小小的系统运转(所...
  • wearenoth
  • wearenoth
  • 2012-07-27 20:49:13
  • 7012

Linux/Android——input子系统核心 (三)

之前的博客有涉及到linux的input子系统,这里学习记录一下input模块. input子系统,作为管理输入设备与系统进行交互的中枢,任何的输入设备驱动都要通过input向内核注册其设备, 常...
  • jscese
  • jscese
  • 2014-12-26 15:10:07
  • 5179

input_register_handler()解析

leesagacious 原创,欢迎转载!
  • leesagacious
  • leesagacious
  • 2015-09-09 00:40:58
  • 1513

Linux的几个子系统

系统调优,就是找出操作系统的瓶颈,并且优化操作系统去减少这些瓶颈。单单靠调整内核的一些参数并不能从根本上解决问题。Linux系统的性能是和几个子系统相关的。这些子系统包括以下四个方面: 1、CPU; ...
  • xygl2009
  • xygl2009
  • 2015-07-14 23:41:03
  • 544

Linux时间子系统之(六):POSIX timer

一、前言 在用户空间接口函数文档中,我们描述了和POSIX timer相关的操作,主要包括创建一个timer、设定timer、获取timer的状态、获取timer overrun的信息、删除ti...
  • G_linuxer_
  • G_linuxer_
  • 2016-03-30 10:30:59
  • 661

Linux内核的5个子系统

首先一张熟悉的图来说明GNU/linux的基本体系结构:         体系的上部分是用户(或应用程序)空间,这是用户应用程序执行的地方。用户空间之下是内核空间,Linux 内核正是位于这里...
  • u012564690
  • u012564690
  • 2014-03-13 21:17:44
  • 3773

Windows10安装Linux子系统Ubuntu

先看看操作系统版本,之前看网上的安装说明很多都是比较早的系统beta版本和现在安装方法有些不一样,我当前的版本为 Windows10 1709 ,家庭版安装使用也是没有问题的下面开始安装,首先确认下你...
  • zsjangel
  • zsjangel
  • 2017-12-12 11:36:32
  • 14483
收藏助手
不良信息举报
您举报文章:linux时间子系统(三)
举报原因:
原因补充:

(最多只允许输入30个字)