From: Christoph Lameter This issue was discussed on lkml and linux-ia64. The patch introduces "getnstimeofday" and removes all the code scaling gettimeofday to nanoseoncs. It makes it possible for the posix-timer functions to return higher accuracy. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton --- 25-akpm/include/linux/time.h | 1 + 25-akpm/kernel/posix-timers.c | 17 ++--------------- 25-akpm/kernel/time.c | 38 ++++++++++++++++++++++++++++++++++++++ 25-akpm/kernel/timer.c | 3 +-- 4 files changed, 42 insertions(+), 17 deletions(-) diff -puN include/linux/time.h~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer include/linux/time.h --- 25/include/linux/time.h~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer 2004-07-26 15:20:23.830526848 -0700 +++ 25-akpm/include/linux/time.h 2004-07-26 15:20:23.840525328 -0700 @@ -348,6 +348,7 @@ extern long do_utimes(char __user * file struct itimerval; extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue); extern int do_getitimer(int which, struct itimerval *value); +extern void getnstimeofday (struct timespec *tv); static inline void set_normalized_timespec (struct timespec *ts, time_t sec, long nsec) diff -puN kernel/posix-timers.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer kernel/posix-timers.c --- 25/kernel/posix-timers.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer 2004-07-26 15:20:23.832526544 -0700 +++ 25-akpm/kernel/posix-timers.c 2004-07-26 15:20:23.840525328 -0700 @@ -1168,15 +1168,10 @@ void exit_itimers(struct signal_struct * */ static int do_posix_gettime(struct k_clock *clock, struct timespec *tp) { - struct timeval tv; - if (clock->clock_get) return clock->clock_get(tp); - do_gettimeofday(&tv); - tp->tv_sec = tv.tv_sec; - tp->tv_nsec = tv.tv_usec * NSEC_PER_USEC; - + getnstimeofday(tp); return 0; } @@ -1192,24 +1187,16 @@ static u64 do_posix_clock_monotonic_gett struct timespec *tp, struct timespec *mo) { u64 jiff; - struct timeval tpv; unsigned int seq; do { seq = read_seqbegin(&xtime_lock); - do_gettimeofday(&tpv); + getnstimeofday(tp); *mo = wall_to_monotonic; jiff = jiffies_64; } while(read_seqretry(&xtime_lock, seq)); - /* - * Love to get this before it is converted to usec. - * It would save a div AND a mpy. - */ - tp->tv_sec = tpv.tv_sec; - tp->tv_nsec = tpv.tv_usec * NSEC_PER_USEC; - return jiff; } diff -puN kernel/time.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer kernel/time.c --- 25/kernel/time.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer 2004-07-26 15:20:23.833526392 -0700 +++ 25-akpm/kernel/time.c 2004-07-26 15:20:23.841525176 -0700 @@ -22,6 +22,9 @@ * "A Kernel Model for Precision Timekeeping" by Dave Mills * Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10) * (Even though the technical memorandum forbids it) + * 2004-07-14 Christoph Lameter + * Added getnstimeofday to allow the posix timer functions to return + * with nanosecond accuracy */ #include @@ -421,6 +424,41 @@ struct timespec current_kernel_time(void EXPORT_SYMBOL(current_kernel_time); +#ifdef CONFIG_TIME_INTERPOLATION +void getnstimeofday (struct timespec *tv) +{ + unsigned long seq,sec,nsec; + + do { + seq = read_seqbegin(&xtime_lock); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec+time_interpolator_get_offset(); + } while (unlikely(read_seqretry(&xtime_lock, seq))); + + while (unlikely(nsec >= NSEC_PER_SEC)) { + nsec -= NSEC_PER_SEC; + ++sec; + } + tv->tv_sec = sec; + tv->tv_nsec = nsec; +} +#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; +} +#endif + +EXPORT_SYMBOL(getnstimeofday); + #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void) { diff -puN kernel/timer.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer kernel/timer.c --- 25/kernel/timer.c~gettimeofday-nanoseconds-patch-makes-it-possible-for-the-posix-timer 2004-07-26 15:20:23.835526088 -0700 +++ 25-akpm/kernel/timer.c 2004-07-26 15:20:23.839525480 -0700 @@ -1243,8 +1243,7 @@ asmlinkage long sys_sysinfo(struct sysin * too. */ - do_gettimeofday((struct timeval *)&tp); - tp.tv_nsec *= NSEC_PER_USEC; + getnstimeofday(&tp); tp.tv_sec += wall_to_monotonic.tv_sec; tp.tv_nsec += wall_to_monotonic.tv_nsec; if (tp.tv_nsec - NSEC_PER_SEC >= 0) { _