时间子系统14_全局时间维护

简介:
//	更新全局时间(由动态时钟调用)
//	函数任务:
//		1.更新last_jiffies_update,记录距离上次更新jiffies经历的ns
//		2.更新jiffies_64,墙上时间,计算cpu负载
//		3.更新下次周期时钟的到期时间
//	注:
//		1.在关中断情况下调用该函数
//		2.last_jiffies_update,记录距离上次更新经历的时钟周期(ns)
1.1 static void tick_do_update_jiffies64(ktime_t now)
{
	unsigned long ticks = 0;
	ktime_t delta;

	write_seqlock(&xtime_lock);
	//距离上次更新jiffies经历的ns
	delta = ktime_sub(now, last_jiffies_update);
	if (delta.tv64 >= tick_period.tv64) {
		//一个时钟周期剩余的ns
		delta = ktime_sub(delta, tick_period);
		//正常情况下,相邻更新的jiffies差一个时钟周期
		last_jiffies_update = ktime_add(last_jiffies_update,
						tick_period);

		//慢速路径:
		//	jiffies距离上次更新的时间超过一个时钟周期
		if (unlikely(delta.tv64 >= tick_period.tv64)) {
			s64 incr = ktime_to_ns(tick_period);
			//剩余的时钟周期
			ticks = ktime_divns(delta, incr);

			last_jiffies_update = ktime_add_ns(last_jiffies_update,
							   incr * ticks);
		}
		//更新jiffies_64,更新墙上时间,计算cpu间负载
		do_timer(++ticks);
		//周期时钟下次到期时间
		tick_next_period = ktime_add(last_jiffies_update, tick_period);
	}
	write_sequnlock(&xtime_lock);
}

//	更新全局时间
//	函数任务:
//		1.更新jiffies_64
//		2.更新墙上时间
//		3.计算cpu间负载
//	调用路径:tick_do_update_jiffies64->do_timer
1.2 void do_timer(unsigned long ticks)
{
	jiffies_64 += ticks;
	update_wall_time();
	calc_global_load();
}

//	更新墙上时间(xtime)
//	函数任务:
//		1.计算距离上次更新墙上时间经历的cycle
//		2.每隔一个NTP间隔相应的cycle数
//			2.1 以clock->cycle_interval为单位,更新clock->cycle_last
//			2.2 以xtime_interval为单位,更新clock->xtime_nsec
//			2.3 进位clock->xtime_nsec到s
//		3.根据NTP矫正clocksource
//		4.更新xtime的纳秒数
//		5.检查是否有更好的时钟源
//	注:
//		#define NTP_SCALE_SHIFT         32
1.3 void update_wall_time(void)
{
	cycle_t offset;
    struct clocksource *clock;
    clock = timekeeper.clock;
    //距离上次更新墙上时间经历的cycle
#ifdef CONFIG_GENERIC_TIME
    offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
#else
    offset = clock->cycle_interval;
#endif
    //墙上时钟的纳秒数
    clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;
    //通过时钟源的cycle计算经历的NTP间隔
    while (offset >= clock->cycle_interval)
    {
    	//以NTP间隔对应的内部时钟cycle更新xtime
		offset -= clock->cycle_interval;
        clock->cycle_last += clock->cycle_interval;
        clock->xtime_nsec += clock->xtime_interval;
        //ns进位到s
        if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
        	clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
        	xtime.tv_sec++;
       		second_overflow();
        }
 
        clock->raw_time.tv_nsec += clock->raw_interval;
        if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) 
        {
        	clock->raw_time.tv_nsec -= NSEC_PER_SEC;
        	clock->raw_time.tv_sec++;
        }
 		//累积时间相对于NTP的误差
        clock->error += tick_length;
        //等效:
        //		1.将t1 = clock->xtime_interval>>clock->shift,得到一个NTP间隔相应的cycle数
        //		2.将t2 = t1<<NTP_SCALE_SHIFT, 放大t1指定的位数
        clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
    }
 	//矫正clocksource
    clocksource_adjust(offset);
    if (unlikely((s64)clock->xtime_nsec < 0)) {
        s64 neg = -(s64)clock->xtime_nsec;
        clock->xtime_nsec = 0;
    	clock->error += neg << (NTP_SCALE_SHIFT - clock->shift);
    }
    //更新xtime的纳秒数
    xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1;
    clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
    clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift);
 	//检查是否有更好的时钟源
    change_clocksource();
}

目录
相关文章
|
人工智能 自然语言处理 安全
AI战略丨新一代 AI 应用: 穿透场景,释放价值
在深入理解技术特性、准确把握应用场景、科学评估实施条件的基础上,企业才能制定出符合自身实际的战略。
|
2月前
|
存储 监控 安全
RFID电动车车牌让出行更安全
RFID电动车车牌通过内置芯片实现车辆身份唯一识别,结合物联网技术,提升防盗、交通秩序、事故处理等多方面的出行安全,助力城市电动车智能化管理,守护市民安全出行。
|
JavaScript 前端开发 Java
《正则表达式经典实例(第2版)》——1.3 正则表达式工具
除非已经拥有了相当长的使用正则表达式编程的经验,否则建议你先在一个工具中试验一下正则表达式,而不是直接在源代码中使用它们。本章和第2章中提供的正则表达式示例都是原始正则表达式,其中并不包含编程语言(即使是Unlx shell)所必需的额外的转义符号。
2561 0
|
网络协议
通俗易懂理解三次握手、四次挥手(TCP)
这篇文章用通俗的语言解释了TCP协议中的三次握手和四次挥手过程,通过比喻和详细的状态变化描述,帮助读者理解建立和断开连接的原理和原因。
通俗易懂理解三次握手、四次挥手(TCP)
|
JSON 数据格式 Docker
Docker 网络命令大全,建议收藏!
【7月更文挑战第22天】
556 7
Docker 网络命令大全,建议收藏!
|
小程序 JavaScript 前端开发
微信小程序开发时数据是否是双向数据绑定的
微信小程序开发时数据是否是双向数据绑定的
|
前端开发 测试技术 Linux
芯片人的快乐——python+systemverilog用波形祝你新春快乐 |献上祝福语波形生成器|
芯片人的快乐——python+systemverilog用波形祝你新春快乐 |献上祝福语波形生成器|
213 0
|
云安全 弹性计算 Kubernetes
玩转ECS第4讲 | 基于弹性计算网络能力提升容器密度最佳实践
云原生和容器化是主流的趋势,实现容器化时推荐大家使用云厂商的容器服务,如阿里云ACK。但由于部分用户因为一些原因需要自建容器,此时不得不面临一个问题,就是如何能够在一台宿主机上提升容器数量,降低容器成本。
玩转ECS第4讲 | 基于弹性计算网络能力提升容器密度最佳实践
|
人工智能 大数据 语音技术
云场景实践研究第90期:四川特驱集团&德康集团
近日,南方农村土墙上一条条人工智能养猪横幅刷爆了朋友圈,不难发现横幅中阿里云、ET大脑、特驱集团、德康集团等字样,押韵喜庆的语言风格背后是人工智能赋能养殖业的落地。2018年2月6日,阿里云与四川特驱集团、德康集团宣布达成合作,将对ET大脑针对性训练与研发,最终全面实现人工智能养猪,项目投入的费用将达数亿。
4579 0