Hi!
I'm working on an integration of current NTP kernel algorithms for Linux 2.6.
xtime now has nanosecond resolution, but there's no POSIX like syscall interface
(clock_getres, clock_gettime, clock_settime) yet.
There's a hacked-on getnstimeofday() which, what I discovered doesn't actually
pass along the nanosecond resolution of xtime. It does:
void getnstimeofday(struct timespec *tv)
{
struct timeval x;
do_gettimeofday(&x);
tv->tv_sec = x.tv_sec;
tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
}
The proper solution most likely is to define POSIX compatible routines with
nanosecond resolution, and then define the microsecond-resolution from those, and
not the other way round.
Also there are severe religious wars on how a clock interface should look like for
a particular architecture. Besides the time interpolator there are architecture-
specific get_offset() calls. While making some people happy, it causes a code
explosion considering amount and complexity of code. I'd strongly prefer one time
variable (xtime) and an interpolator for the time elapsed since xtime was updates,
combinded with a method how to get consistent time. That's bad IMHO.
To make a long story short, here's a patch (just for inspiring you) I made to get
the nanoseconds available to other modules and to user land (via new methods
outside this patch):
Index: kernel/time.c
===================================================================
RCS file: /root/LinuxCVS/Kernel/kernel/time.c,v
retrieving revision 1.1.1.6.2.1
diff -u -r1.1.1.6.2.1 time.c
--- kernel/time.c 11 Feb 2006 18:16:28 -0000 1.1.1.6.2.1
+++ kernel/time.c 12 Feb 2006 17:30:51 -0000
@@ -1405,26 +1407,36 @@
}
EXPORT_SYMBOL(timespec_trunc);
-#ifdef CONFIG_TIME_INTERPOLATION
+/* get system time with nanosecond accuracy */
void getnstimeofday (struct timespec *tv)
{
- unsigned long seq,sec,nsec;
-
+ unsigned long seq, nsec, sec, offset;
do {
seq = read_seqbegin(&xtime_lock);
+#ifdef CONFIG_TIME_INTERPOLATION
+ offset = time_interpolator_get_offset();
+#else
+ offset = 0;
+#endif
sec = xtime.tv_sec;
- nsec = xtime.tv_nsec+time_interpolator_get_offset();
+ nsec = xtime.tv_nsec + offset;
} while (unlikely(read_seqretry(&xtime_lock, seq)));
+#ifdef CONFIG_TIME_INTERPOLATION
while (unlikely(nsec >= NSEC_PER_SEC)) {
nsec -= NSEC_PER_SEC;
++sec;
}
+#endif
tv->tv_sec = sec;
tv->tv_nsec = nsec;
}
EXPORT_SYMBOL_GPL(getnstimeofday);
+#ifdef CONFIG_TIME_INTERPOLATION
+/* this is a mess: there are also architecture-dependent ``do_gettimeofday()''
+ * and ``do_settimeofday()''
+ */
int do_settimeofday (struct timespec *tv)
{
time_t wtm_sec, sec = tv->tv_sec;
@@ -1451,42 +1463,14 @@
void do_gettimeofday (struct timeval *tv)
{
- unsigned long seq, nsec, usec, sec, offset;
- do {
- seq = read_seqbegin(&xtime_lock);
- offset = time_interpolator_get_offset();
- sec = xtime.tv_sec;
- nsec = xtime.tv_nsec;
- } while (unlikely(read_seqretry(&xtime_lock, seq)));
+ struct timespec ts;
- usec = (nsec + offset) / 1000;
-
- while (unlikely(usec >= USEC_PER_SEC)) {
- usec -= USEC_PER_SEC;
- ++sec;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
+ getnstimeofday(&ts);
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = (ts.tv_nsec + 500) / 1000;
}
EXPORT_SYMBOL(do_gettimeofday);
-
-
-#else
-/*
- * Simulate gettimeofday using do_gettimeofday which only allows a timeval
- * and therefore only yields usec accuracy
- */
-void getnstimeofday(struct timespec *tv)
-{
- struct timeval x;
-
- do_gettimeofday(&x);
- tv->tv_sec = x.tv_sec;
- tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
-}
-EXPORT_SYMBOL_GPL(getnstimeofday);
#endif
void getnstimestamp(struct timespec *ts)
Regards,
Ulrich
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]