summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2004-08-22 22:47:16 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:47:16 -0700
commitb9cbc585eda36c84edbf05c0e83e3bf950ff45fa (patch)
treeb23b0f8016bcfc8e256f5a61fa20803ba4ffada1 /kernel
parent346ed9c13aab9be890a8bd52d06fd6761876bb85 (diff)
[PATCH] gettimeofday nanoseconds patch
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 <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/posix-timers.c17
-rw-r--r--kernel/time.c38
-rw-r--r--kernel/timer.c3
3 files changed, 41 insertions, 17 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 42c24868837c..f2d93f698e4f 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1168,15 +1168,10 @@ void exit_itimers(struct signal_struct *sig)
*/
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_gettime_parts(
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 --git a/kernel/time.c b/kernel/time.c
index 68c22f2bf452..b0bdef2b7f20 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -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 <linux/module.h>
@@ -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 --git a/kernel/timer.c b/kernel/timer.c
index 4850abbeacdc..79db45d06bac 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1241,8 +1241,7 @@ asmlinkage long sys_sysinfo(struct sysinfo __user *info)
* 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) {