< Linux Kernel > Measuring Time

The kernel often needs to measure how much time has passed since a given moment. For example, a routine
that carries on a CPU-intensive task often releases the CPU after a given amount of time. It will continue its
job when it is rescheduled for execution. This is especially important in kernel code, even though the kernel
supports kernel preemption. A common example in the networking code is given by the routines that

implement garbage collection.


The passing of time in kernel space is measured in ticks . A tick is the time between two consecutive
expirations of the timer interrupt. The timer takes care of different tasks (we are not interested in them here)
and regularly expires HZ times per second. HZ is a variable initialized by architecture-dependent code. For
example, it is initialized to 1,000 on i386 machines. This means that the timer interrupt expires 1,000 times
per second when Linux runs on an i386 system, and that there is one millisecond between two consecutive
expirations.


Every time the timer expires it increments the global variable called jiffies. This means that at any time,

jiffies represents the number of ticks since the system booted, and the generic value n*HZ represents n
seconds of time.


If all a function needs is to measure the passing of time, it can save the value of jiffies into a local

variable and later compare the difference between jiffies and that timestamp against a time interval
(expressed in number of ticks) to see how much time has passed since measurement started.
The following example shows a function that needs to do some kind of work but does not want to hold the
CPU for more than one tick. When do_something says the work is completed by setting job_done to a
nonzero value, the function can return:


unsigned long start_time = jiffies;

int job_done = 0;
do {
   do_something(&job_done);
   If (job_done)
      return;
while (jiffies - start_time < 1);


Comparing Times


To compare the temporal relation of events, the kernel provides several auxiliary functions that prevent
off-by-one errors if they are used instead of a home-grown comparisons (a, b, and c denote jiffie time
values for some events):

❑ timer_after(a,b) returns true if time a is after time b. time_before(a,b) will be true if time a
   is before time b, as you will have guessed.
❑ time_after_eq(a,b) works like time_after, but also returns true if both times are identical.
   time_before_eq(a,b) is the inverse variant.
❑ time_in_range(a,b,c) checks if time a is contained in the time interval denoted by [b, c]. The
   boundaries are included in the range, so a may be identical to b or c.

Using these functions ensures that wraparounds of the jiffies counter are handled correctly. As a general
rule, kernel code should therefore never compare time values directly, but always use these functions.


Time Conversion

When it comes to time intervals, jiffies might not be the unit of choice in the minds of most programmers.
It is more conventional to think in milliseconds or microseconds for short time intervals. The kernel thus
provides some auxiliary functions to convert back and forth between these units and jiffies:

<jiffies.h>
unsigned int jiffies_to_msecs(const unsigned long j);
unsigned int jiffies_to_usecs(const unsigned long j);
unsigned long msecs_to_jiffies(const unsigned int m);
unsigned long usecs_to_jiffies(const unsigned int u);

The functions are self-explanatory. However, Section 15.2.3 shows that conversion functions between
jiffies and struct timeval and struct timespec, respectively, are also available.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值