Linux内核-时钟子系统
文章平均质量分 88
linux内核 时间 子系统
生活需要深度
这个作者很懒,什么都没留下…
展开
-
《Linux/Unix系统编程手册》 时间子系统
两个重要的结构体:定时器参数struct itimerval和表示时间struct timerval。/* Current value (time until next expiration) */ 为0则是一次性定时器。setitimer和alarm原型:setitimer可以指定三种不同类型定时器:ITIMER_REAL(SIGALARM)、ITIMER_VIRTUAL(SIGVTALRM)、ITIMER_PROF(SIGPROF)。原创 2023-02-08 09:01:21 · 873 阅读 · 0 评论 -
Linux中的休眠函数
在中断处理函数中是不能够做延时,耗时,甚至休眠的操作,即中断处理函数只能够做简短,不耗时的,紧急的事情。但是有的时候在中断到来的时候又希望做耗时的操作,所以就产生了矛盾。在内核启动的时候默认会启动一个events线程,这个线程维护了一个工作队列,如果你向这个工作队列中提交work,并唤醒这个休眠的进程,此时就可以回调工作队列的底半部处理函数。tasklet是基于软中断实现的,tasklet没有个数限制,tasklet工作在中断上下文,里面可以做相对耗时的操作,但是不能够做休眠的操作。原创 2023-02-07 18:59:47 · 6397 阅读 · 0 评论 -
Linux时间子系统之四:Timer在用户和内核空间流程
所以无论是alarm/setitimer,还是POSIX Timer都是通过发送signal来通知用户应用。只是用户空间处理消息的方式有所不同。由于Timer经过库的封装,不光要看内核,还需要研究库对API进行了何种封装。才能更好的了解其行为。也由于库的种类(lig/glib/ulib等)和版本千差万别,所以也需要引起重视。一个关于libpthread引起的POSIX Timer执行异常情况。描述:在一个进程中创建三个SIGEV_THREAD类型POSIX Timer,但是超时只执行一个回调函数。原创 2023-02-06 18:39:24 · 365 阅读 · 0 评论 -
Linux时间子系统之三:jiffies
jiffies记录了系统启动以来,经过了多少tick。一个tick代表多长时间,在内核的CONFIG_HZ中定义。比如CONFIG_HZ=200,则一个jiffies对应5ms时间。所以内核基于jiffies的定时器精度也是5ms。原创 2023-02-07 19:19:56 · 1700 阅读 · 0 评论 -
Linux时间子系统之二:Alarm Timer
--------------------------------------初始化一个struct rtc_timer,将其加入struct rtc_device的timerqueue红黑树里面。--------------------------------------------将timer->node插入rtc->timerqueue。------------------------返回注册的Wakeup Source,alarmtimer_suspend使用。原创 2023-02-07 19:18:51 · 885 阅读 · 0 评论 -
Linux时间子系统之一:认识timer_list和timer_stats和使用
--------------------------------------------------------------------tick_sched部分,参照结构体解释-----------------------------------------------------------------------------input.timer = timer;---------------------------------------------------填充entry结构体。原创 2023-02-07 19:21:49 · 612 阅读 · 0 评论 -
Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)
但是在tick_nohz_handler的最后,tick_device一定会被编程为紧跟着的下一个tick周期的时刻被触发,如果刚才的定时器处理后,并没有激活新的进程,我们的期望是周期时钟可以用下一个新的定时器重新计算可以停止的时间,而不是下一个tick时刻,但是tick_nohz_handler却仅仅简单地把tick_device的到期时间设为下一个周期的tick时刻,这导致了周期时钟被恢复,显然这不是我们想要的。在进入和退出中断时,因为动态时钟的关系,中断系统需要作出一些配合。原创 2023-02-07 18:52:25 · 710 阅读 · 0 评论 -
Linux时间子系统之八:定时器的应用--createtimer()
高精度时钟下对应的timer定时处理函数的调用和基本处理流程。原创 2023-02-07 16:56:22 · 1335 阅读 · 0 评论 -
Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()
这里的循环体实现比较怪异,它使用hrtimer_active函数间接地判断定时器是否到期,如果hrtimer_active返回false,说明定时器已经过期,然后把hrtimer_sleeper结构的task字段设置为NULL,从而导致循环体的结束,另一个结束条件是当前进程收到了信号事件,所以,当因为是定时器到期而退出时,do_nanosleep返回true,否则返回false,上述的hrtimer_nanosleep正是利用了这一特性来决定它的返回值。到这个时候,进程已经被调度走,那它如何返回继续执行?原创 2023-02-07 16:30:01 · 1097 阅读 · 0 评论 -
Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
上一篇文章,我介绍了传统的低分辨率定时器的实现原理。而随着内核的不断演进,大牛们已经对这种低分辨率定时器的精度不再满足,而且,硬件也在不断地发展,系统中的定时器硬件的精度也越来越高,这也给高分辨率定时器的出现创造了条件。内核从2.6.16开始加入了高精度定时器架构。在实现方式上,内核的高分辨率定时器的实现代码几乎没有借用低分辨率定时器的数据结构和代码,内核文档给出的解释主要有以下几点:低分辨率定时器的代码和jiffies的关系太过紧密,并且默认按32位进行设计,并且它的代码已经经过长时间的优化,目前的使用也原创 2023-02-07 16:11:03 · 1552 阅读 · 0 评论 -
Linux时间子系统之五:低分辨率定时器的原理和实现
通过上面的讨论,我们可以发现,内核的低分辨率定时器的实现非常精妙,既实现了大量定时器的管理,又实现了快速的O(1)查找到期定时器的能力,利用巧妙的数组结构,使得只需在间隔256个tick时间才处理一次迁移操作,5个数组就好比是5个齿轮,它们随着base->timer_jifffies的增长而不停地转动,每次只需处理第一个齿轮的某一个齿节,低一级的齿轮转动一圈,高一级的齿轮转动一个齿,同时自动把即将到期的定时器迁移到上一个齿轮中,所以低分辨率定时器通常又被叫做时间轮:time wheel。原创 2023-02-07 14:39:21 · 189 阅读 · 0 评论 -
Linux时间子系统之四:定时器的引擎:clock_event_device
早期的内核版本中,进程的调度基于一个称之为tick的时钟滴答,通常使用时钟中断来定时地产生tick信号,每次tick定时中断都会进行进程的统计和调度,并对tick进行计数,记录在一个jiffies变量中,定时器的设计也是基于jiffies。这时候的内核代码中,几乎所有关于时钟的操作都是在machine级的代码中实现,很多公共的代码要在每个平台上重复实现。随后,随着通用时钟框架的引入,内核需要支持高精度的定时器,为此,通用时间框架为定时器硬件定义了一个标准的接口:clock_event_device,mach原创 2023-02-07 15:12:50 · 337 阅读 · 0 评论 -
Linux时间子系统之三:时间的维护者:timekeeper
本系列文章的前两节讨论了用于计时的时钟源:clocksource,以及内核内部时间的一些表示方法,但是对于真实的用户来说,我们感知的是真实世界的真实时间,也就是所谓的墙上时间,clocksource只能提供一个按给定频率不停递增的周期计数,如何把它和真实的墙上时间相关联?本节的内容正是要讨论这一点。1. 时间的种类内核管理着多种时间,它们分别是:RTC时间wall time:墙上时间monotonic timeraw monotonic timeboot time:总启动时间RTC时间 在PC原创 2023-02-06 16:50:05 · 330 阅读 · 0 评论 -
Linux时间子系统之二:表示时间的单位和结构
系统时间是由CPU主芯片的定时器进行维护的时间,一般情况下都会选择芯片上精度最高的定时器作为系统时间的定时基准,以避免在系统运行较长时间后出现大的时间偏移。现在主流CPU都是64位的,使用64位的数据表示时间也是顺其自然的事,用64位的有符号数来表示时间,可以表示到292,277,026,596年12月4日15时30分08秒,相信我们再也不用愁时间回归的问题了。此后操作系统使用的时间都是系统时间,如果没有显式的通过命令去控制RTC的读写操作,系统将不会再从RTC中去获取或者同步设置时间。原创 2023-02-02 16:20:12 · 464 阅读 · 0 评论 -
Linux时间子系统之一:clock source(时钟源)
从转换精度考虑,mult的值是越大越好,但是为了计算过程不发生溢出,mult的值又不能取得过大。定时器周期性地(0.5秒)检查watchdog_list上的clocksource,WATCHDOG_THRESHOLD的值定义为0.0625秒,如果在0.5秒内,clocksource的偏差大于这个值就表示这个clocksource是不稳定的,定时器的回调函数通过clocksource_watchdog_kthread线程标记该clocksource,并把它的rate修改为0,表示精度极差。原创 2023-02-06 14:39:37 · 660 阅读 · 0 评论 -
Linux内核 RTC时间架构
驱动注册成功后会构建rtc_device结构体表征的rtc设备,并把rtc芯片的操作方式存放到rtc设备的ops成员中。同时发现rtc0文件为指向/sys/devices/platform/fe5e0000.i2c/i2c-5/5-0051/rtc/rtc0的符号链接,在瑞芯微的系统中,安卓部分程序其实最终也是依赖**/sys/class/rtc/rtc0** 下的文件节点实现时间管理功能的。rtc-lib.c:文件提供通用的时间操作函数,如rtc_time_to_tm、rtc_valid_tm等。原创 2023-02-02 16:34:34 · 1027 阅读 · 0 评论 -
Linux时间子系统之(十七):ARM generic timer驱动代码分析
我们在写PXA270的timer硬件驱动的时候是毫无压力的,而在写S3C2451的timer的驱动的时候,最大的愿望就是把三星的HW timer的设计人员拉出来打一顿。只要有一个没有定义,那么就出错退出了。compatible 属性用于驱动匹配的,在系统启动的时候,系统中的所有的device node形成一个树状结构,在clock source初始化的时候进行device node和driver匹配(compatible 字符串的比对),device node携带的信息会在初始化的时候传递给具体的驱动。原创 2023-01-30 14:27:25 · 1353 阅读 · 0 评论 -
Linux时间子系统之(十六):clockevent
(1)底层的硬件驱动知道自己的能力,可以通过struct clock_event_device中的features成员宣称自己的功能:CLOCK_EVT_FEAT_PERIODIC说明该硬件timer可以产生周期性的clock event,CLOCK_EVT_FEAT_ONESHOT说明自己只能产生one shot类型的clock event。在注册clock event device的时候已经设定这个参数了,就是struct clock_event_device的min_delta_ns这个成员。原创 2023-02-01 14:25:14 · 472 阅读 · 0 评论 -
Linux时间子系统之(十五):clocksource
一、前言和洋葱一样,软件也是有层次的,内核往往需要对形形色色的某类型的驱动进行抽象,屏蔽掉其具体的特质,获取该类驱动共同的逻辑,而又根据这些逻辑撰写该类驱动的抽象层。嵌入式系统总是会提供timer的硬件block,软件需要对timer硬件提供的功能进行抽象:linux kernel将timer类型的硬件抽象成两个组件,一是free running的counter,另外一个是指定的counter值上产生中断的能力。本文主要描述第一个组件,在内核中被称作clock source。二、什么是clocksource原创 2023-02-01 16:02:05 · 1172 阅读 · 0 评论 -
Linux时间子系统之(十四):tick broadcast framework
我们假设当前时间点是X秒,broadcast tick当前设定的next event的触发时间点是X+5秒,如果cpu申请的时间晚于当前设定的时间,例如X+7秒,那么什么也不需要做,保持当前的设定,如果cpu申请的时间早于当前设定的时间,例如X+3秒,那么broadcast tick会立刻修改next event的触发时间点为X+3秒,以便满足3秒后唤醒该cpu的需求(当然,这时候一定要设定irq affinity,将该全局timer的中断定向到该CPU CORE)。为什么可以这么做呢?原创 2023-02-03 15:30:24 · 1327 阅读 · 0 评论 -
Linux时间子系统之(十三):Tick Device layer综述
一、前言时间子系统中的tick device layer主要涉及kernel/time/tick-*相关的文件,本文的主要内容就是从high level层次(不纠缠在具体的每行代码)描述tick device layer的运作逻辑。如果说每个.c文件是一个模块的话,我们可以首先简单描述tick device layer的各个模块。tick-common.c描述了tick device的一些通用操作,此外,该文件还包括了周期性tick的代码。想要让系统工作在tickless mode(更准确应该是Dynami原创 2023-02-02 11:06:51 · 404 阅读 · 0 评论 -
Linux时间子系统之(十二):periodic tick
(a)该clock event device对应的HW timer必须是和该CPU core是有关联的的(也就是说,该hw timer的中断是可以送达到该CPU core的)。的文章中,我们知道:底层的timer硬件驱动在初始化的时候会注册clock event device,在注册过程中就会调用tick_check_new_device函数来看看是否需要进行tick device的初始化,如果已经已经初始化OK的tick device是否有更换更高精度clock event device的需求。原创 2023-02-02 10:13:40 · 454 阅读 · 0 评论 -
Linux时间子系统之(六):POSIX timer
一、前言在用户空间接口函数文档中,我们描述了和POSIX timer相关的操作,主要包括创建一个timer、设定timer、获取timer的状态、获取timer overrun的信息、删除timer。本文将沿着这些用户空间的接口定义来看看内核态的实现。虽然POSIX timer可以基于各种不同的clock创建,本文主要描述real time clock相关的timer。本文第二章描述了POSIX timer的基本原理,第三章描述系统调用的具体实现,第四章主要讲real time clock的timer ca原创 2023-02-03 15:19:22 · 780 阅读 · 0 评论 -
Linux时间子系统之(五):POSIX Clock
CLOCK_BOOTTIME和CLOCK_MONOTONIC类似,也是单调上述,在系统初始化的时候设定的基准数值是0,不过CLOCK_BOOTTIME计算系统suspend的时间,也就是说,不论是running还是suspend(这些都算是启动时间),CLOCK_BOOTTIME都会累积计时,直到系统reset或者shutdown。process_cpu_clock_getres用来获取时间精度,该函数实际是调用posix_cpu_clock_getres(PROCESS_CLOCK, tp)来完成的。原创 2023-02-03 15:20:46 · 783 阅读 · 0 评论 -
Linux时间子系统之(四):timekeeping
monotonic clock是从一个固定点开始作为epoch,对于linux,就是启动的时间点,因此,monotonic clock是一个从0开始增加的clock,并且不接受用户的setting,看起来好象适合boot clock是一致的,不过它们之间唯一的差别是对系统进入suspend的处理,对于monotonic clock,它是不记录系统睡眠时间的,因此monotonic clock得到的是一个system uptime。不过,要保证在timekeeping初始化的时候是ready的。原创 2023-02-03 15:21:51 · 915 阅读 · 0 评论 -
Linux时间子系统之(三):用户空间接口函数
需要指出的是MONOTONIC类型的时钟不是绝对时间的概念,多半是计算两个采样点之间的时间,并且保证采样点之间时间的单调性。gettimeofday函数可以获取从linux epoch到当前时间点的秒数以及微秒数(在内核态,这个时间值仍然是通过timekeeper模块获得的,具体接口是getnstimeofday64,该接口的时间精度是纳秒级别的,不过没有关系,除以1000就获得微秒级别的精度了),settimeofday则是设定从linux epoch到当前时间点的秒数以及微秒数。原创 2023-02-03 15:22:46 · 824 阅读 · 0 评论 -
Linux时间子系统之(二):软件架构
这里听起来名字是高大上,实际上,这里仅仅是借用了新时间子系统的名词,对于旧的内核,clock event就是通过timer硬件的中断处理函数完成的,在此基础上可以构建tick模块,tick模块维护了系统的tick,例如系统存在10ms的tick,每次tick到来的时候,timekeeping模块就增加系统时间,如果timekeeping完全是tick驱动,那么它精度只能是10ms,为了更高精度,clock source模块就是一个提供tick之间的offset时间信息的接口函数。这个选项和实时应用相关。原创 2023-02-01 17:01:16 · 656 阅读 · 0 评论 -
Linux时间子系统之(一):时间的基本概念
当然,了解狭义相对论的同学应该是可以建立起来自己的时空观,其实没有绝对的时间和空间(时间和空间是相对的而且是有关联的,组成四维时空),同时是相对的(相对于自己的参考系),事件A和事件B先后发生,位于不同的惯性参考系的观察者可以不同的观测结果,可能一个认为A和B相关1秒,而另外一个惯性参考系的人认为A和B之间相隔1.2秒。我们可以用平均太阳日的1/86400来定义,也可以用绕太阳轨道公转一年的时间来定义秒,但是这种基于天体运动而定义的秒其实是不精准的,因为地球的自转和公转的时间不是一个恒定的值。原创 2023-02-03 16:19:21 · 503 阅读 · 0 评论 -
时钟与Linux时钟 - 前传
时钟或者钟表(clock)是一种计时工具,每个人都至少有一块,可能在你的手机里,也可能佩戴在你的手腕上。原创 2023-01-13 14:15:01 · 408 阅读 · 0 评论