The real-time clock now uses gettimeofday rather than the tsc. This improves portability and provides better behavior in the presence of slowed or suspended CPUs. Signed-off-by: Paolo 'Blaisorblade' Giarrusso --- um-linux-2.4.27-paolo/arch/um/include/os.h | 2 + um-linux-2.4.27-paolo/arch/um/kernel/time.c | 37 ----------------------- um-linux-2.4.27-paolo/arch/um/kernel/time_kern.c | 22 ++++++------- um-linux-2.4.27-paolo/arch/um/os-Linux/Makefile | 2 - um-linux-2.4.27-paolo/arch/um/os-Linux/time.c | 21 +++++++++++++ um-linux-2.4.27-paolo/arch/um/sys-i386/Makefile | 2 - um-linux-2.4.27/arch/um/sys-i386/time.c | 24 -------------- 7 files changed, 36 insertions(+), 74 deletions(-) diff -puN /dev/null arch/um/os-Linux/time.c --- /dev/null 2005-04-15 01:44:05.698330744 +0200 +++ um-linux-2.4.27-paolo/arch/um/os-Linux/time.c 2005-04-15 11:12:52.000000000 +0200 @@ -0,0 +1,21 @@ +#include +#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 -L arch/um/sys-i386/time.c -puN arch/um/sys-i386/time.c~use-gettimeofday /dev/null --- um-linux-2.4.27/arch/um/sys-i386/time.c +++ /dev/null 2005-04-15 01:44:05.698330744 +0200 @@ -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: - */ diff -puN arch/um/sys-i386/Makefile~use-gettimeofday arch/um/sys-i386/Makefile --- um-linux-2.4.27/arch/um/sys-i386/Makefile~use-gettimeofday 2005-04-15 11:12:52.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/sys-i386/Makefile 2005-04-15 11:12:52.000000000 +0200 @@ -6,7 +6,7 @@ O_TARGET = built-in.o obj-y = bugs.o checksum.o extable.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 export-objs = ksyms.o USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o diff -puN arch/um/os-Linux/Makefile~use-gettimeofday arch/um/os-Linux/Makefile --- um-linux-2.4.27/arch/um/os-Linux/Makefile~use-gettimeofday 2005-04-15 11:12:52.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/os-Linux/Makefile 2005-04-15 11:12:52.000000000 +0200 @@ -5,7 +5,7 @@ O_TARGET = built-in.o -obj-y = file.o process.o tty.o +obj-y = file.o process.o time.o tty.o include $(TOPDIR)/Rules.make diff -puN arch/um/include/os.h~use-gettimeofday arch/um/include/os.h --- um-linux-2.4.27/arch/um/include/os.h~use-gettimeofday 2005-04-15 11:12:52.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/include/os.h 2005-04-15 11:12:52.000000000 +0200 @@ -166,6 +166,8 @@ extern int os_protect_memory(void *addr, 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_kern.c~use-gettimeofday arch/um/kernel/time_kern.c --- um-linux-2.4.27/arch/um/kernel/time_kern.c~use-gettimeofday 2005-04-15 11:12:52.000000000 +0200 +++ um-linux-2.4.27-paolo/arch/um/kernel/time_kern.c 2005-04-15 11:12:52.000000000 +0200 @@ -18,6 +18,7 @@ #include "user_util.h" #include "time_user.h" #include "mode.h" +#include "os.h" extern rwlock_t xtime_lock; @@ -36,10 +37,10 @@ int timer_irq_inited = 0; int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS]; static int first_tick; -static unsigned long long prev_tsc; +static unsigned long long prev_usecs; static long long delta; /* Deviation per interval */ -extern unsigned long long host_hz; +#define MILLION 1000000 void timer_irq(union uml_pt_regs *regs) { @@ -54,21 +55,20 @@ void timer_irq(union uml_pt_regs *regs) if(first_tick){ #if defined(CONFIG_UML_REAL_TIME_CLOCK) - unsigned long long tsc; /* We've had 1 tick */ - tsc = time_stamp(); + unsigned long long usecs = os_usecs(); - delta += tsc - prev_tsc; - prev_tsc = tsc; + delta += usecs - prev_usecs; + prev_usecs = usecs; - 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; } @@ -142,7 +142,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 6) - end[6] = '\0'; - rest = strtoul(end, NULL, 10); - while(mult-- > 0) - rest *= 10; - } - - return(1000000 * mhz + rest); -} - -unsigned long long host_hz = 0; - void time_init(void) { /* XXX This is to fill xtime with something real - otherwise by the @@ -124,7 +88,6 @@ void time_init(void) */ timer(); - host_hz = get_host_hz(); if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) panic("Couldn't set SIGVTALRM handler"); set_interval(ITIMER_VIRTUAL); _