时间子系统9_timekeeper初始化

简介:
//Timekeeping
//	Timekeeping子系统负责更新xtime, 调整误差, 及提供get/settimeofday接口.
//Times in Kernel
//kernel的time基本类型:
//	1) system time
//		A monotonically increasing value that represents the amount of time the system has been running. 
//		单调增长的系统运行时间, 可以通过time source, xtime及wall_to_monotonic计算出来.
//	2) wall time
//		A value representing the the human time of day, as seen on a wrist-watch. Realtime时间: xtime.
//	3) time source
//		A representation of a free running counter running at a known frequency, usually in hardware, e.g GPT. 
//		可以通过clocksource->read()得到counter值
//	4) tick
//		A periodic interrupt generated by a hardware-timer, typically with a fixed interval defined by HZ: jiffies
//	这些time之间互相关联, 互相可以转换:
//		system_time = xtime + cyc2ns(clock->read() - clock->cycle_last) + wall_to_monotonic;
//		real_time = xtime + cyc2ns(clock->read() - clock->cycle_last)
//		也就是说real time是从1970年开始到现在的nanosecond, 而system time是系统启动到现在的nanosecond.
//		这两个是最重要的时间, 由此hrtimer可以基于这两个time来设置过期时间. 所以引入两个clock base.
//	参考:http://blog.csdn.net/hongjiujing/article/details/7070746

//	全局timekeeper
1.1 struct timekeeper timekeeper;
//	timekeeper框架初始化
//		初始化clocksource
//	调用路径:start_kernel->timekeeping_init
//	函数任务:
//		1.使用默认时间源初始化全局timekeeper
//		2.初始化墙上时间xtime
//		3.初始化wall_to_monotonic,使其与xtime相加得到系统启动以来的单调时间
//	注:
//		Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,
//		它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,
//		它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒).
1.2 static void __init timekeeping_init(void)
{
	struct clocksource *clock;
	unsigned long flags;
	struct timespec now, boot;
	//通过cmos获取当前时间
	read_persistent_clock(&now);
	//系统启动时的时间
	read_boot_clock(&boot);
	write_seqlock_irqsave(&xtime_lock, flags);
	//ntp初始化
	ntp_init();
	//x86架构下默认的时钟源,jiffies_clocksource
	clock = clocksource_default_clock();
	//使能时钟源
	if (clock->enable)
		clock->enable(clock);
	//使用clocksource初始化全局timekeeper
	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;
	//如果体系结构没有提供read_boot_clock,设置启动时间为当前时间
	if (boot.tv_sec == 0 && boot.tv_nsec == 0) {
		boot.tv_sec = xtime.tv_sec;
		boot.tv_nsec = xtime.tv_nsec;
	}
	//通过将wall_to_monotonic加到xtime,获取系统启动以来的单调时间
	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_sequnlock_irqrestore(&xtime_lock, flags);
}

//	timekeeper初始化
//	函数任务:
//		1.绑定timekeeper到clocksource
//		2.换算NTP间隔为clocksource的cycle
//	调用路径:timekeeping_init->timekeeper_setup_internals
//	注:
//		1.timekeeper.cycle_interval,一个NTP间隔对应的时钟cycle
//		2.timekeeper.xtime_interval, 一个NTP间隔对应的时钟cycle*mult
//		3.timekeeper.raw_interval,	一个NTP间隔(近似值)
1.3 static void timekeeper_setup_internals(struct clocksource *clock)
{
	cycle_t interval;
	u64 tmp;
	//timekeeper使用提供的时钟源
	timekeeper.clock = clock;
	clock->cycle_last = clock->read(clock);

	//NTP_INTERVAL_LENGTH转换为clocksource的cycle
	tmp = NTP_INTERVAL_LENGTH;
	tmp <<= clock->shift;
	tmp += clock->mult/2;
	do_div(tmp, clock->mult);
	if (tmp == 0)
		tmp = 1;

	//一个NTP间隔对应的时钟cycle
	interval = (cycle_t) tmp;
	timekeeper.cycle_interval = interval;

	//一个NTP间隔对应的xtime间隔
	timekeeper.xtime_interval = (u64) interval * clock->mult;
	//
	timekeeper.raw_interval =
		((u64) interval * clock->mult) >> clock->shift;

	timekeeper.xtime_nsec = 0;
	//使用时钟源的shift
	timekeeper.shift = clock->shift;
	//累积的时间相对于NTP的误差
	timekeeper.ntp_error = 0;
	timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;
	timekeeper.mult = clock->mult;

}

目录
相关文章
|
缓存 数据挖掘 计算机视觉
砥砺的前行|基于labview的机器视觉图像处理|NI Vision Assisant(五)——Grayscale(灰度图) 功能
砥砺的前行|基于labview的机器视觉图像处理|NI Vision Assisant(五)——Grayscale(灰度图) 功能
854 0
砥砺的前行|基于labview的机器视觉图像处理|NI Vision Assisant(五)——Grayscale(灰度图) 功能
|
机器学习/深度学习 弹性计算 缓存
阿里云服务器经济型e实例与通用算力型u1实例对比分析与选择指南
在阿里云服务器的实例规格中,经济型e实例和通用算力型u1实例是很多个人和普通企业级用户常见的选择,经济型e实例与通用算力型u1实例的主要区别在于性能、应用场景及价格策略。本文将详细对比这两种实例的性能、应用场景及价格策略,以供参考。
|
Java 开发工具 Android开发
搭建大型源码阅读环境——使用 OpenGrok
RTFSC 是程序员成长的必修课,营造舒适的环境至关重要。本文介绍了阅读大型源码(如 AOSP)的工具选择,重点推荐了免费开源的 OpenGrok。OpenGrok 提供快速搜索、版本历史查看、语法高亮等功能,适用于特大型项目。文章还详细讲解了 OpenGrok 的安装和配置步骤,帮助读者高效阅读源码。
2468 6
|
存储 内存技术
【RAID磁盘阵列服务器数据恢复】华为OceanStor Dorado存储系统RAID-TP数据丢失数据恢复案例
客户报告其华为OceanStor Dorado存储系统的RAID-TP出现故障,导致数据丢失。RAID-TP是一种增强型RAID级别,包含数据磁盘、校验磁盘和转换磁盘,可在两个磁盘故障时仍保护数据。通过分析RAID结构与工作原理,我们制定了恢复方案:首先从校验磁盘读取信息并计算出丢失的数据块,接着将恢复的数据写入新磁盘。由于缺乏现成工具,需定制RAID重组程序以恢复数据。华为的动态RAID重构技术保证了重构过程中冗余级别的稳定。
295 1
讲真的,遇到接口自协商故障,可以试着这样处理!
讲真的,遇到接口自协商故障,可以试着这样处理!
622 1
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp微信小程序的校园外卖平台的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的校园外卖平台的详细设计和实现
229 0
基于SpringBoot+Vue+uniapp微信小程序的校园外卖平台的详细设计和实现
|
缓存 小程序
【微信小程序-原生开发】启动时自动升级更新到最新版本
【微信小程序-原生开发】启动时自动升级更新到最新版本
367 0
|
监控 算法 关系型数据库
MySQL学习笔记- 刷脏页(flush)对性能的影响
MySQL学习笔记- 刷脏页(flush)对性能的影响
924 0
【AXI】解读AXI协议双向握手机制的原理
【AXI】解读AXI协议双向握手机制的原理
【AXI】解读AXI协议双向握手机制的原理
|
Linux Shell 开发工具
MacOS安装Homebrew与Oh-My-Zsh
MacOS安装Homebrew与Oh-My-Zsh
5333 0