From: Jeff Dike <jdike@addtoit.com>

There are a whole bunch of reasons to use gettimeofday rather than rdtsc,
so this patch does just that.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/um/include/os.h       |    1 
 25-akpm/arch/um/kernel/time.c      |   38 -------------------------------------
 25-akpm/arch/um/kernel/time_kern.c |   30 +++++++++++++++--------------
 25-akpm/arch/um/os-Linux/Makefile  |    4 +--
 25-akpm/arch/um/os-Linux/time.c    |   21 ++++++++++++++++++++
 25-akpm/arch/um/sys-i386/Makefile  |    2 -
 25-akpm/arch/um/sys-i386/time.c    |   24 -----------------------
 7 files changed, 41 insertions(+), 79 deletions(-)

diff -puN arch/um/include/os.h~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/include/os.h
--- 25/arch/um/include/os.h~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/include/os.h	Tue Sep 14 18:29:04 2004
@@ -166,6 +166,7 @@ extern int os_protect_memory(void *addr,
 			     int r, int w, int x);
 extern int os_unmap_memory(void *addr, int len);
 extern void os_flush_stdout(void);
+extern unsigned long long os_usecs(void);
 
 #endif
 
diff -puN arch/um/kernel/time.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/kernel/time.c
--- 25/arch/um/kernel/time.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/kernel/time.c	Tue Sep 14 18:29:04 2004
@@ -10,7 +10,6 @@
 #include <sys/time.h>
 #include <signal.h>
 #include <errno.h>
-#include <string.h>
 #include "user_util.h"
 #include "kern_util.h"
 #include "user.h"
@@ -95,49 +94,12 @@ void uml_idle_timer(void)
 	set_interval(ITIMER_REAL);
 }
 
-static unsigned long long get_host_hz(void)
-{
-	char mhzline[16], *end;
-	unsigned long long mhz;
-	int ret, mult, rest, len;
-
-	ret = cpu_feature("cpu MHz", mhzline,
-			  sizeof(mhzline) / sizeof(mhzline[0]));
-	if(!ret)
-		panic ("Could not get host MHZ");
-
-	mhz = strtoul(mhzline, &end, 10);
-
-	/* This business is to parse a floating point number without using
-	 * floating types.
-	 */
-
-	rest = 0;
-	mult = 0;
-	if(*end == '.'){
-		end++;
-		len = strlen(end);
-		if(len < 6)
-			mult = 6 - len;
-		else if(len > 6)
-			end[6] = '\0';
-		rest = strtoul(end, NULL, 10);
-		while(mult-- > 0)
-			rest *= 10;
-	}
-
-	return(1000000 * mhz + rest);
-}
-
-unsigned long long host_hz = 0;
-
 extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
 
 void time_init(void)
 {
 	struct timespec now;
 
-	host_hz = get_host_hz();
 	if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
 		panic("Couldn't set SIGVTALRM handler");
 	set_interval(ITIMER_VIRTUAL);
diff -puN arch/um/kernel/time_kern.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/kernel/time_kern.c
--- 25/arch/um/kernel/time_kern.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/kernel/time_kern.c	Tue Sep 14 18:29:04 2004
@@ -20,6 +20,7 @@
 #include "user_util.h"
 #include "time_user.h"
 #include "mode.h"
+#include "os.h"
 
 u64 jiffies_64;
 
@@ -42,12 +43,10 @@ unsigned long long sched_clock(void)
 int timer_irq_inited = 0;
 
 static int first_tick;
-static unsigned long long prev_tsc;
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
+static unsigned long long prev_usecs;
 static long long delta;   		/* Deviation per interval */
-#endif
 
-extern unsigned long long host_hz;
+#define MILLION 1000000
 
 void timer_irq(union uml_pt_regs *regs)
 {
@@ -61,22 +60,25 @@ void timer_irq(union uml_pt_regs *regs)
 	}
 
 	if(first_tick){
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
-		unsigned long long tsc;
+#if defined(CONFIG_UML_REAL_TIME_CLOCK)
 		/* We've had 1 tick */
-		tsc = time_stamp();
+		unsigned long long usecs = os_usecs();
+
+		delta += usecs - prev_usecs;
+		prev_usecs = usecs;
 
-		delta += tsc - prev_tsc;
-		prev_tsc = tsc;
+		/* Protect against the host clock being set backwards */
+		if(delta < 0)
+			delta = 0;
 
-		ticks += (delta * HZ) / host_hz;
-		delta -= (ticks * host_hz) / HZ;
+		ticks += (delta * HZ) / MILLION;
+		delta -= (ticks * MILLION) / HZ;
 #else
 		ticks = 1;
 #endif
 	}
 	else {
-		prev_tsc = time_stamp();
+		prev_usecs = os_usecs();
 		first_tick = 1;
 	}
 
@@ -151,7 +153,7 @@ void __udelay(um_udelay_t usecs)
 {
 	int i, n;
 
-	n = (loops_per_jiffy * HZ * usecs) / 1000000;
+	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	for(i=0;i<n;i++) ;
 }
 
@@ -159,7 +161,7 @@ void __const_udelay(um_udelay_t usecs)
 {
 	int i, n;
 
-	n = (loops_per_jiffy * HZ * usecs) / 1000000;
+	n = (loops_per_jiffy * HZ * usecs) / MILLION;
 	for(i=0;i<n;i++) ;
 }
 
diff -puN arch/um/os-Linux/Makefile~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/os-Linux/Makefile
--- 25/arch/um/os-Linux/Makefile~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/os-Linux/Makefile	Tue Sep 14 18:29:04 2004
@@ -3,9 +3,9 @@
 # Licensed under the GPL
 #
 
-obj-y = file.o process.o tty.o user_syms.o drivers/
+obj-y = file.o process.o time.o tty.o user_syms.o drivers/
 
-USER_OBJS := $(foreach file,file.o process.o tty.o,$(obj)/$(file))
+USER_OBJS := $(foreach file,file.o process.o time.o tty.o,$(obj)/$(file))
 
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff -puN /dev/null arch/um/os-Linux/time.c
--- /dev/null	Thu Apr 11 07:25:15 2002
+++ 25-akpm/arch/um/os-Linux/time.c	Tue Sep 14 18:29:04 2004
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+#include <sys/time.h>
+
+unsigned long long os_usecs(void)
+{
+	struct timeval tv;
+
+	gettimeofday(&tv, NULL);
+	return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -puN arch/um/sys-i386/Makefile~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/sys-i386/Makefile
--- 25/arch/um/sys-i386/Makefile~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/sys-i386/Makefile	Tue Sep 14 18:29:04 2004
@@ -1,5 +1,5 @@
 obj-y = bitops.o bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o \
-	ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o
+	ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_MODULES) += module.o
diff -puN arch/um/sys-i386/time.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc arch/um/sys-i386/time.c
--- 25/arch/um/sys-i386/time.c~uml-convert-the-real-time-clock-to-gettimeofday-from-rdtsc	Tue Sep 14 18:29:04 2004
+++ 25-akpm/arch/um/sys-i386/time.c	Tue Sep 14 18:29:04 2004
@@ -1,24 +0,0 @@
-/*
- * sys-i386/time.c
- * Created 		25.9.2002	Sapan Bhatia
- *
- */
-
-unsigned long long time_stamp(void)
-{
-	unsigned long low, high;
-
-	asm("rdtsc" : "=a" (low), "=d" (high));
-	return((((unsigned long long) high) << 32) + low);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
_