Knowing the Current Time

Kernel code can always retrieve the current time by looking at the value of jiffies. Usually, the fact that the value represents only the time since the last boot is not relevant to the driver, because its life is limited to the system uptime. Drivers can use the current value of jiffies to calculate time intervals across events (for example, to tell double clicks from single clicks in input device drivers). In short, looking at jiffies is almost always sufficient when you need to measure time intervals, and if you need very sharp measures for short time lapses, processor-specific registers come to the rescue.

It’s quite unlikely that a driver will ever need to know the wall-clock time, since this knowledge is usually needed only by user programs such as cron and at. If such a capability is needed, it will be a particular case of device usage, and the driver can be correctly instructed by a user program, which can easily do the conversion from wall-clock time to the system clock. Dealing directly with wall-clock time in a driver is often a sign that policy is being implemented, and should thus be looked at closely.

If your driver really needs the current time, the do_gettimeofday function comes to the rescue. This function doesn’t tell the current day of the week or anything like that; rather, it fills a struct timeval pointer—the same as used in the gettimeofday system call—with the usual seconds and microseconds values. The prototype for do_gettimeofday is:

 #include <linux/time.h>
 void do_gettimeofday(struct timeval *tv);

The source states that do_gettimeofday has “near microsecond resolution” for many architectures. The precision does vary from one architecture to another, however, and can be less in older kernels. The current time is also available (though with less precision) from the xtime variable (a struct timeval); however, direct use of this variable is discouraged because you can’t atomically access both the timeval fields tv_sec and tv_usec unless you disable interrupts. As of the 2.2 kernel, a quick and safe way of getting the time quickly, possibly with less precision, is to call get_fast_time:

 void get_fast_time(struct timeval *tv);

Code for reading the current time is available within the jit (“Just In Time”) module in the source files provided on the O’Reilly FTP site. jit creates a file called /proc/currentime, which returns three things in ASCII when read:

  • The current time as returned by do_gettimeofday

  • The current time as found in xtime

  • The current jiffies value

We chose to use a dynamic /proc file because it requires less module code—it’s not worth creating a whole device just to return three lines of text.

If you use cat to read the file multiple times in less than a timer tick, you’ll see the difference between xtime and do_gettimeofday, reflecting the fact that xtime is updated less frequently:

morgana%cd /proc; cat currentime currentime currentime
gettime: 846157215.937221
xtime:   846157215.931188
jiffies: 1308094
gettime: 846157215.939950
xtime:   846157215.931188
jiffies: 1308094
gettime: 846157215.942465
xtime:   846157215.941188
jiffies: 1308095

Get Linux Device Drivers, Second Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.