From: Jeff Dike There are a whole bunch of reasons to use gettimeofday rather than rdtsc, so this patch does just that. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton --- 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 #include #include -#include #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 +#include + +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: - */ _