您的位置 首页 观点

需求了解的linux HZ Tick Jiffies

需要了解的linux HZ Tick Jiffies-Jiffies为Linux核心变数(32位元变数,unsigned long),它被用来纪录系统自开几以来,已经过多少的tick。每发生一次timer interrupt,Jiffies变数会被加一。

  linux HZ

  Linux中心几个重要跟时间有关的名词或变数,底下将介绍HZ、tick与jiffies。

  HZ

  Linux中心每隔固定周期会宣布TImer interrupt (IRQ 0),HZ是用来界说每一秒有几回TImer interrupts。举例来说,HZ为1000,代表每秒有1000次TImer interrupts。 HZ可在编译中心时设定,如下所示(以中心版别2.6.20-15为例):

  adrian@adrian-desktop:~$ cd /usr/src/linux

  adrian@adrian-desktop:/usr/src/linux$ make menuconfig

  Processor type and features —》 TImer frequency (250 HZ) —》

  其 中HZ可设定100、250、300或1000。以小弟的中心版别预设值为250。

  小试验

  调查/proc/interrupt的 timer中止次数,并于一秒后再次调查其值。理论上,两者应该相差250左右。

  adrian@adrian-desktop:~$ cat /proc/interrupts | grep timer && sleep 1 && cat /proc/interrupts | grep timer

  0: 9309306 IO-APIC-edge timer

  0: 9309562 IO-APIC-edge timer

  上 面四个栏位分别为中止号码、CPU中止次数、PIC与设备称号。

  要查看体系上HZ的值是什么,就履行命令

  cat /boot/config-`uname -r` | grep ‘^CONFIG_HZ=’

  还能够直接更改文件

  os/linux/include/asm-cris/param.h?

  Tick

  Tick是HZ的倒数,意即timer interrupt每发生一次中止的时间。如HZ为250时,tick为4毫秒(millisecond)。

  Jiffies

  Jiffies为Linux中心变数(32位元变数,unsigned long),它被用来纪录体系自开几以来,现已过多少的tick。每发生一次timer interrupt,Jiffies变数会被加一。值得留意的是,Jiffies于体系开机时,并非初始化成零,而是被设为-300*HZ (arch/i386/kernel/time.c),即代表体系于开机五分钟后,jiffies便会溢位。那溢位怎么办?事实上,Linux中心界说几 个macro(timer_after、time_after_eq、time_before与time_before_eq),即便是溢位,也能藉由这 几个macro正确地获得jiffies的内容。

  别的,80×86架构界说一个与jiffies相关的变数jiffies_64 ,此变数64位元,要比及此变数溢位或许要好几百万年。因而要比及溢位这刻发生应该很难吧。那怎么经由jiffies_64获得jiffies资讯呢?事 实上,jiffies被对应至jiffies_64最低的32位元。因而,经由jiffies_64能够彻底不理睬溢位的问题便能获得jiffies。

  HZ的设定:

  #make menuconfig

  processor type and features—》Timer frequency (250 HZ)—》

  HZ的不同值会影响timer (节拍)中止的频率

  2.2 jiffies及其溢出

  全局变量jiffies取值为自操作体系启动以来的时钟滴答的数目,在头文 件中界说,数据类型为unsigned long volatile (32位无符号长整型)。关于 jiffies为什么要选用volatile来限制,可参阅《关于volatile和jiffies.txt》。

  jiffies转换为秒可选用 公式:(jiffies/HZ)核算,将秒转换为jiffies可选用公式:(seconds*HZ)核算。

  当时钟中止发生时,jiffies 值就加1。因而接连累加一年又四个多月后就会溢出(假定HZ=100,1个jiffies等于1/100秒,jiffies可记载的最大秒数为 (2^32 -1)/100=42949672.95秒,约合497天或1.38年),即当取值抵达最大值时持续加1,就变为了0。

  在 Vxworks操作体系中,界说HZ的值为60,因而接连累加两年又三个多月后也将溢出(jiffies可记载的最大秒数为约合2.27年)。假如在 Vxworks操作体系上的运用程序对jiffies的溢出没有加以充分考虑,那么在接连运转两年又三个多月后,这些运用程序还能够安稳运转吗?

  下 面咱们来考虑jiffies的溢出,咱们将从以下几个方面来论述:

  。 无符号整型溢出的详细进程

  。 jiffies溢出形成程序逻辑 犯错

  。 Linux内核怎么来避免jiffies溢出

  。 time_after等比较时间先/后的宏背面的原理

  。 代码中 运用time_after等比较时间先/后的宏

  3. 无符号整型溢出的详细进程

  咱们首要来看看无符号长整型(unsigned long)溢出的详细进程。实践上,无符号整型的溢出过 程都很相似。为了更详细地描绘无符号长整型溢出的进程,咱们以8位无符号整型为例来加以阐明。

  8位无符号整型从0开端持续增加,当增加到最大值 255时,持续加1将变为0,然后该进程循环往复:

  0, 1, 2, 。.., 253, 254, 255,

  0, 1, 2, 。.., 253, 254, 255,

  。..

  4. jiffies溢出形成程序逻辑犯错

  下面,经过一个比方来看jiffies的溢出。

  例4-1:jiffies溢出形成程 序逻辑犯错

  unsigned long timeout = jiffies + HZ/2; /* timeout in 0.5s */

  /* do some work 。.. */

  do_somework();

  /* then see whether we took too long */

  if (timeout 》 jiffies) {

  /* we did not time out, call no_timeout_handler() 。.. */

  no_timeout_handler();

  } else {

  /* we timed out, call timeout_handler() 。.. */

  timeout_handler();

  }

  本 例的意图是从当时时间起,假如在0.5秒内履行完do_somework(),则调用no_timeout_handler()。假如在0.5秒后履行完 do_somework(),则调用timeout_handler()。

  咱们来看看本例中一种或许的溢出状况,即在设置timeout并履行 do_somework()后,jiffies值溢出,取值为0。设在设置timeout后,timeout的值接近无符号长整型的最大值,即小于 2^32-1。设履行do_somework()花费了1秒,那么代码应当调用timeout_handler()。可是当jiffies值溢出取值为0 后,条件timeout 》 jiffies建立,jiffies值(等于0)小于timeout(接近但小于2^32-1),尽管从逻辑上讲 jiffies值要比timeout大。但终究代码调用的是no_timeout_handler(),而不是timeout_handler()。

  5. Linux内核怎么来避免jiffies溢出

  Linux内核中供给了以下四个宏,可有效地处理由于jiffies溢出而形成程序逻 辑犯错的状况。下面是从Linux Kernel 2.6.7版别中摘取出来的代码:

  /*

  * These inlines deal with timer wrapping correctly. You are

  * strongly encouraged to use them

  * 1. Because people otherwise forget

  * 2. Because if the timer wrap changes in future you won‘t have to

  * alter your driver code.

  *

  * time_after(a,b) returns true if the time a is after time b.

  *

  * Do this with “《0” and “》=0” to only test the sign of the result. A

  * good compiler would generate better code (and a really good compiler

  * wouldn’t care)。 Gcc is currently neither.

  */

  #define time_after(a,b) \

  (typecheck(unsigned long, a) && \

  typecheck(unsigned long, b) && \

  ((long)(b) – (long)(a) 《 0))

  #define time_before(a,b) time_after(b,a)

  #define time_after_eq(a,b) \

  (typecheck(unsigned long, a) && \

  typecheck(unsigned long, b) && \

  ((long)(a) – (long)(b) 》= 0))

  #define time_before_eq(a,b) time_after_eq(b,a)

  在宏time_after中,首要保证两个输入参数a和b的数据类型为unsigned long,然后才履行实践的比较。这是今后编码中应当留意 的当地。

  6. time_after等比较时间先后的宏背面的原理

  那么,上述time_after等比较时间先/后的宏为什么能够处理 jiffies溢出形成的过错状况呢?

  咱们依然以8位无符号整型(unsigned char)为例来加以阐明。模仿上面的 time_after宏,咱们能够给出简化的8位无符号整型对应的after宏:

  #define uc_after(a, b) ((char)(b) – (char)(a) 《 0)

  设a和b的数据类型为unsigned char,b为接近8位无符号整型最大值邻近的一个固定值254,下面给出跟着a(设其初始值为254)变 化而得到的核算值:

  a b (char)(b) – (char)(a)

  254 254 0

  255 – 1

  0 – 2

  1 – 3

  。..

  124 -126

  125 -127

  126 -128

  127 127

  128 126

  。..

  252 2

  253 1

  从上面的核算能够看出,设定b不变,跟着a(设其初始值为254)不断增加1,a的取值改动为:

  254, 255, (一次发生溢出)

  0, 1, 。.., 124, 125, 126, 127, 126, 。.., 253, 254, 255, (二 次发生溢出)

  0, 1, 。..

  。..

  而(char)(b) – (char)(a)的改动为:

  0, -1,

  -2, -3, 。.., -126, -127, -128, 127, 126, 。.., 1, 0, -1,

  -2, -3, 。..

  。..

  从上面的详细进程能够看出,当a取值为254,255, 接着在(一次发生溢出)之后变为0,然后增加到127之前,uc_after(a,b)的 成果都显现a是在b之后,这也与咱们的预期相符。但在a取值为127之后,uc_after(a,b)的成果却显现a是在b之前。

  从上面的运算 进程能够得出以下定论:

  运用uc_after(a,b)宏来核算两个8位无符号整型a和b之间的巨细(或先/后,before/after), 那么a和b的取值应当满意以下限制条件:

  。 两个值之间相差从逻辑值来讲应小于有符号整型的最大值。

  。 关于8位无符号整型,两个值 之间相差从逻辑值来讲应小于128。

  从上面能够类推出以下定论:

  关于time_after等比较jiffies先/后的宏,两个值的 取值应当满意以下限制条件:

  两个值之间相差从逻辑值来讲应小于有符号整型的最大值。

  关于32位无符号整型,两个值之间相差从逻辑值来 讲应小于2147483647。

  关于HZ=100,那么两个时间值之间相差不应当超越2147483647/100秒 = 0.69 年 = 248.5天。关于HZ=60,那么两个时间值之间相差不应当超越2147483647/60秒 = 1.135年。在实践代码运用中,需求比较 先/后的两个时间值之间一般都相差很小,规模大致在1秒~1天左右,所以以上time_after等比较时间先/后的宏彻底能够放心肠用于实践的代码 中。

  7. 代码中运用time_after等比较时间先/后的宏

  下面代码是针对例4-1修正后的正确代码:

  例7-1:在例4-1基 础上运用time_before宏后的正确代码

  unsigned long timeout = jiffies + HZ/2; /* timeout in 0.5s */

  /* do some work 。.. */

  do_somework();

  /* then see whether we took too long */

  if (time_before(jiffies, timeout)) {

  /* we did not time out, call no_timeout_handler() 。.. */

  no_timeout_handler();

  } else {

  /* we timed out, call timeout_handler() 。.. */

  timeout_handler();

  }

  8. 定论

  体系中选用jiffies来核算时间,但由于jiffies溢出或许形成时间比较的过错,因而强烈建议在编码中运用 time_after等宏来比较时间先后联系,这些宏能够放心运用。

  内核时钟:

  内核运用硬件供给的不一起钟来供给依赖于时间的服务,如busy-waiting(糟蹋CPU周期)和sleep-waiting(抛弃CPU)

  HZ and Jiffies

  体系时钟以可编程的频率中止处理器,这个频率即每秒滴答数,记载在HZ,挑选适宜的HZ值是个重要问题,并且HZ值是架构相关的,能够在装备菜单中修正。 【2.6.21核供给了对tickless kernel(CONFIG_NO_HZ)的支撑,它会依据体系负载动态触发时钟中止】。

  jiffies记载了体系启动后的滴答数,常用的函数:time_before()、 time_after()、time_after_eq()、time_before_eq()。由于jiffies随时钟滴答改动,不能 用编译器优化它,应取volatile值。

  32位jiffies变量会在50天后溢出,太小,因而内核供给变量jiffies_64来hold 64位jiffies。该64位的低32位即为jiffies,在32位机上需求两天指令来赋值64位数据,不是原子的,因而内核供给函数 get_jiffies_64()。

  Long Delays

  busy-wait:timebefore(),使CPU忙等候;sleep-wait:shedule_timeout(到时间);不管在内核空间还 是用户空间,都没有比HZ更准确的操控了,由于时间片都是依据滴答更新的,并且即便界说了您的进程在超越指守时间后运转,调度器也或许依据优先级挑选其他 进程履行。

  sleep-wait():wait_event_timeout()用于在满意某个条件或超时后从头履行,msleep()睡觉指定的ms后从头进入就 绪行列,这些长推延仅适用于进程上下文,在中止上下文中不能睡觉也不能长时间busy-waiting。

  内核供给了timer API来在必守时间后履行某个函数:

  #include

  struct timer_list my_timer;

  init_timer(&my_timer); /* Also see setup_timer() */

  my_timer.expire = jiffies + n*HZ; /* n is the timeout in number

  of seconds */

  my_timer.function = timer_func; /* Function to execute

  after n seconds */

  my_timer.data = func_parameter; /* Parameter to be passed

  to timer_func */

  add_timer(&my_timer); /* Start the timer */

  假如您想周期性履行上述代码,那么把它们参加timer_func()函数。您运用mod_timer()来改动my_timer的 超时值,del_timer()来删掉my_timer, 用timer_pending()查看是否my_timer处于挂起状况。

  用户空间函数clock_settime()和clock_gettime()用 于获取内核时钟服务。用户运用程序运用setitimer()和getitimer()来操控alarm信号的传递当指定超时发生后。

  Short Delays

  前面评论的sleep-wait不适用,只能用busy-wait办法。内核用于short delay的有mdelay()、udelay()、ndelay()。

  Busy-waiting关于short durations的完结是经过衡量处理器履行一条指令和必要数量的重复loop来完结的,依据loops_per_jiffy完结。

  Pentium Time Stamp Counter

  Time Stamp Counter(TSC)是一个64位寄存器,仅出现在飞跃兼容机上,记载了自启动后处理器耗费的clock cycles数目。TSC是以processor cycle速率增加的,运用rdtsc()读 取,供给微秒级的准确度。TSC ticks能够经过除以CPU时钟速率来转换成秒数,这能够从cpu_khz读 取。

  unsigned long low_tsc_ticks0, high_tsc_ticks0;

  unsigned long low_tsc_ticks1, high_tsc_ticks1;

  unsigned long exec_time;

  rdtsc(low_tsc_ticks0, high_tsc_ticks0); /* Timestamp

  before */

  printk(“Hello World\n”); /* Code to be

  profiled */

  rdtsc(low_tsc_ticks1, high_tsc_ticks1); /* Timestamp after */

  exec_time = low_tsc_ticks1 – low_tsc_ticks0;

  从核2.6.21现已供给high-resolution timers(CONFIG_HIGH_RES_TIMERS), 它运用硬件相关高速时钟来供给高准确度的功用函数如nanosleep()。飞跃机上运用 TSC完结该功用。

  Real Time Clock

  RTC时钟track肯守时间,记载在非易失性存储器中。RTC电池常超越computer生存期。能够用RTC完结以下功用:(1)、读或设置肯守时 钟,并在clock updates时发生中止;(2)以2HZ到8192HZ来发生周期性中止;(3)设置alarms。

  jiffies仅是相关于体系启动的相对时间,假如想获取absolute time或wall time,则需求运用RTC,内核用变量xtime来记载,当体系启动时,读取RTC并记载 在xtime中,当体系halt时,则将wall time写回RTC,函数do_gettimeofday()来读取wall time。

  #include

  static struct timeval curr_time;

  do_gettimeofday(&curr_time);

  my_timestamp = cpu_to_le32(curr_time.tv_sec); /* Record timestamp */

  用户空间获取wall time的函数:time()回来calendar time或从00:00:00 on January 1,1970的秒数;(2)localtime():回来calendar time in broken-down format;(3)mktime():与 localtime()相反;(4)gettimeofday()以microsecond 准确度回来calendar时间(需硬件支撑)

  别的一个获取RTC的办法是经过字符设备/dev/rtc,一个时间仅答应一个处理器拜访它。

  时钟和守时器对Linux内核来说十分重要。首要内核要办理体系的运转时间(uptime)和当时墙上时间(wall time), 即当时实践时间。其次,内核中很多的活动由时间驱动(time driven)。其间一些活动是周期性的,比方调度调度器(scheduler)中的运转行列(runqueue)或许改写屏幕这样的活动,它们以固有的 频率守时发生;一起,内核要非周期性地调度某些函数在未来某个时间发生,比方推延履行的磁盘I/O操作等。

  实时时钟

  ———————————————————

  内核有必要凭借硬件来完结时间办理。实时时钟(real time clock)是用来耐久寄存体系时间的设备,它与CMOS集成在一起,并经过主板电池供电,所以即便在封闭核算机体系之后,实时时钟依然能持续作业。

  体系启动时,内核读取实时时钟,将所读的时间寄存在变量xtime中作为墙上时间(wall time),xtime保存着从1970年1月1日0:00到当时时间所阅历的秒数。尽管在Intel x86机器上,内核会周期性地将当时时间存回实时时钟中,但应该清晰,实时时钟的首要效果便是在启动时初始化墙上时间xtime。

  体系守时器与动态守时器

  ———————————————————

  周期性发生的工作都是由体系守时器(system timer)驱动。在X86体系结构上,体系守时器通常是一种可编程硬件芯片(如8254 CMOS芯片),又称可编程距离守时器(PIT, Programmable Interval Timer),其发生的中止便是时钟中止(timer interrupt)。时钟中止对应的处理程序担任更新体系时间和履行周期性运转的使命。体系守时器的频率称为节拍率(tick rate),在内核中表明为HZ。

  以X86为例,在2.4之前的内核中其巨细为100; 从内核2.6开端,HZ = 1000, 也便是说每秒时钟中止发生1000次。这一改动使得体系守时器的精度(resolution)由10ms进步到1ms,这大大进步了体系关于时间驱动工作 调度的准确性。过于频频的时钟中止不行避免地增加了体系开支(overhead),可是总的来说,在现在核算机体系上,HZ = 1000不会导致难以承受的体系开支。

  与体系守时器相对的是动态守时器(dynamic timer),它是调度工作(履行调度程序)在未来某个时间发生的机遇。内核能够动态地创立或毁掉动态守时器。

  体系守时器及其间止处理程序是内核办理机制的中枢,下面是一些运用体系守时器周期履行的作业(中止处理程序所做的作业):

  (1) 更新体系运转时间(uptime)

  (2) 更新当时墙上时间(wall time)

  (3) 在对称多处理器体系(SMP)上,均衡调度各处理器上的运转行列

  (4) 查看当时进程是否用完了时间片(time slice),假如竭尽,则进行从头调度

  (5) 运转超时的动态守时器

  (6) 更新资源耗尽和处理器时间的核算值

  内核动态守时器依赖于体系时钟中止,由于只要在体系时钟中止发生后内核才会去查看当时是否有超时的动态守时器。

  X86体系结构中时钟资源还包含CPU本地APIC(local Advanced Programmable Interrupt Controller)中的守时器和时间戳计时器TSC(Time Stamp Counter)。高精度守时器将运用CPU本地APIC作为高精度守时中止源。

  高精度守时器的规划与完结

  ———————————————————

  X86体系结构中,内核2.6.X的HZ = 1000, 即体系时钟中止履行粒度为1ms,这意味着体系中周期工作最快为1ms履行一次,而不或许有更高的精度。动态守时器随时都或许超时,但由于只要在体系时钟 中止到来时内核才会查看履行超时的动态守时器,所以动态守时器的平均误差大约为半个体系时钟周期(即0.5ms)。

  关于实时要求较高的电信运用来说,一般Linux在实时性方面与电信渠道的要求之间还存在必定的距离。CGL为了增强Linux的软实时才能,在以下方面 对内核进行了改善:供给高精度的动态守时器;供给可抢占式内核(preemption kernel)等。下面首要介绍高精度实时器的规划思维及完结,该完结遵从PISIX 1003.1b中时钟和守时器相关API规范,便利运用程序开发人员的运用。

  高精度守时器的根本规划思维为:用 (jiffies+sub_jiffie)表明动态守时器的超时时间,PIT依然按频率HZ = 1000发生体系时钟中止。假如在一个时钟中止tick与下一个时钟中止(tick+1)之间,即[jiffies, jiffies+1)之间,有高精度动态守时器等候处理(超时时间表明为(jiffies+sub_jiffie), sub_jiffie 《 1), 那么用最近的动态守时器超时值sub_jiffie对硬件守时器(PIT或local APIC)进行设定,使其在时间(jiffies+sub_jiffie)发生中止,告诉内核对该高精度守时器进行处理。而不用总是比及体系时钟中止到来 后才查看履行一切超时的守时器,然后到达进步动态守时器精度的意图。

  高精度守时器的中止源

  ———————————————————

  高精度守时器在内核中,依然运用可编程距离守时器PIC发生每秒HZ次的体系时钟中止,关于选用哪种硬件守时器发生高精度守时器中止则取决于CPU上是否 有本地APIC。若CPU上没有本地APIC,那么仍可运用PIT发生高精度守时中止,尽管这种然PIT即发生体系时钟中止又发生高精度守时器中止的做法 功率不高。

  获取高精度守时器的发生时间

  ———————————————————

  高精度守时器发生在接连两个jiffies之间(即时间(jiffies+sub_jiffie)),要确认其发生时间,就有必要确认sub_jiffie 的巨细。经过函数get_arch_cycles(ref_jiffies)可获取sub_jiffie的值,sub_jiffe以CPU时钟周期为最小 计时单位。函数详细完结思维是,经过拜访计数器TSC,核算从上一个jiffies到当时时间ref_jiffies之间的TSC差值,终究确认 sub_jiffies的巨细。

  The high-resolution timer API

  ———————————————————

  Last September, this page featured an article on the ktimers patch by Thomas Gleixner. The new timer abstraction was designed to enable the provision of high-resolution timers in the kernel and to address some of the inefficiencies encountered when the current timer code is used in this mode. Since then, there has been a large amount of discussion, and the code has seen significant work. The end product of that work, now called “hrtimers,” was merged for the 2.6.16 release.

  At its core, the hrtimer mechanism remains the same. Rather than using the “timer wheel” data structure, hrtimers live on a time-sorted linked list, with the next timer to expire being at the head of the list. A separate red/black tree is also used to enable the insertion and removal of timer events without scanning through the list. But while the core remains the same, just about everything else has changed, at least superficially.

  struct ktime_t

  —————————–

  There is a new type, ktime_t, which is used to store a time value in nanoseconds. This type, found in , is meant to be used as an opaque structure. And, interestingly, its definition changes depending on the underlying architecture. On 64-bit systems, a ktime_t is really just a 64-bit integer value in nanoseconds. On 32-bit machines, however, it is a two-field structure: one 32-bit value holds the number of seconds, and the other holds nanoseconds. The order of the two fields depends on whether the host architecture is big-endian or not; they are always arranged so that the two values can, when needed, be treated as a single, 64-bit value. Doing things this way complicates the header files, but it provides for efficient time value manipulation on all architectures.

  struct–ktime_t

  typedef union {

  On 64-bit systems

  |———————-|

  | s64 tv64; |

  |———————-|

  On 32-bit machines

  |———————-|

  | struct { |

  | s32 sec, nsec; |

  | s32 nsec, sec; |

  | } tv; |

  |———————-|

  } ktime_t;

  初始化ktime_t

  —————————–

  A whole set of functions and macros has been provided for working with ktime_t values, starting with the traditional two ways to declare and initialize them(ktime_t values):

  (1) Initialize to zero

  DEFINE_KTIME(name);

  (2) ktime_t kt;

  kt = ktime_set(long secs, long nanosecs);

  初始化高精度时钟hrtimer

  —————————–

  The interface for hrtimers can be found in 。 A timer is represented by struct hrtimer, which must be initialized with:

  void hrtimer_init(struct hrtimer *timer, clockid_t which_clock);

  System clocks

  —————————–

  Every hrtimer is bound to a specific clock. The system currently supports two clocks, being:

  * CLOCK_MONOTONIC: a clock which is guaranteed always to move forward in time, but which does not reflect “wall clock time” in any specific way. In the current implementation, CLOCK_MONOTONIC resembles the jiffies tick count in that it starts at zero when the system boots and increases monotonically from there.

  * CLOCK_REALTIME which matches the current real-world time.

  The difference between the two clocks can be seen when the system time is adjusted, perhaps as a result of administrator action, tweaking by the network time protocol code, or suspending and resuming the system. In any of these situations, CLOCK_MONOTONIC will tick forward as if nothing had happened, while CLOCK_REALTIME may see discontinuous changes. Which clock should be used will depend mainly on whether the timer needs to be tied to time as the rest of the world sees it or not. The call to hrtimer_init() will tie an hrtimer to a specific clock, but that clock can be changed with:

  void hrtimer_rebase(struct hrtimer *timer, clockid_t new_clock);

  hrtimer_start()

  —————————–

  Actually setting a timer is accomplished with:

  int hrtimer_start(struct hrtimer *timer,

  ktime_t time,

  enum hrtimer_mode mode);

  The mode parameter describes how the time parameter should be interpreted. A mode of HRTIMER_ABS indicates that time is an absolute value, while HRTIMER_REL indicates that time should be interpreted relative to the current time.

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/89657.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部