Commit d4f558bc authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: convert the real-time clock to gettimeofday from rdtsc

There are a whole bunch of reasons to use gettimeofday rather than rdtsc,
so this patch does just that.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 58b08935
......@@ -166,6 +166,7 @@ extern int os_protect_memory(void *addr, unsigned long len,
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
......
......@@ -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);
......
......@@ -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++) ;
}
......
......@@ -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 $@ $<
/*
* sys-i386/time.c
* Created 25.9.2002 Sapan Bhatia
*
*/
#include <stdlib.h>
#include <sys/time.h>
unsigned long long time_stamp(void)
unsigned long long os_usecs(void)
{
unsigned long low, high;
struct timeval tv;
asm("rdtsc" : "=a" (low), "=d" (high));
return((((unsigned long long) high) << 32) + low);
gettimeofday(&tv, NULL);
return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec);
}
/*
......
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment