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 (I used it to tell double clicks from single clicks in the kmouse module). In short, looking at jiffies is almost always sufficient when you need to measure time intervals.

It’s quite unlikely that a driver will ever need to know the wall-clock time, as this knowledge is usually needed only by user programs like 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.

If your driver really needs the current time, the do_gettimeofday function comes to the rescue. The function doesn’t tell the current day of the week or anything like that; rather, it fills a struct timeval pointer with the usual seconds-microseconds values. It responds to the following prototype:

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

The source states that do_gettimeofday has ``near microsecond resolution'' for all architectures except the Alpha and the Sparc, where it has the same resolution as jiffies. The Sparc port has been upgraded in 2.1.34 to support fine-grained time measures. 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. Using the timeval structure filled by do_gettimeofday is much safer.

Unfortunately, do_gettimeofday was not exported by Linux 1.2. If you need to know the current time and want to be backward compatible, you should resort to the following version of the function:

#if LINUX_VERSION_CODE < VERSION_CODE(1,3,46)
/* 
 * kernel headers already declare the function as non-static.
 * We reimplement it with another name, and #define it
 */
extern inline void redo_gettimeofday(struct timeval *tv)
{
    unsigned long flags;

    save_flags(flags);
    cli();
    *tv = xtime;
    restore_flags(flags);
}
#define do_gettimeofday(tv) redo_gettimeofday(tv)
#endif

This version is coarser than the real function because it uses only the current value of the xtime structure, which is no more fine-grained than jiffies. However, it is portable across Linux platforms. The ``real'' function attains better resolution by querying the real-time clock through architecture-dependent code.

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 the current time in ASCII when it is read. I chose to use a dynamic /proc file because it requires less module code--it’s not worth creating a whole device just to return two lines of text.

If you use cat to read the file multiple times in less than a timer tick, you’ll appreciate the difference between xtime and do_gettimeofday:

morgana% cat /proc/currentime /proc/currentime /proc/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
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.200.226