Match delay/DELAY on x86 with delay(9). It takes an unsigned int as
argument. Use this and replace the inline assembly (mul + div using the 64bit intermediate result) with normal 32bit multiplication and division. The compiler can turn the division into a multiplication and shift, making it even cheaper then the original assembly. For extreme long delays, just use 64bit arithmetic.
This commit is contained in:
parent
c71c45f606
commit
930e1f6e1d
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.64 2007/10/18 15:28:32 yamt Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.65 2007/10/26 13:24:39 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007
|
||||
|
@ -73,7 +73,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.64 2007/10/18 15:28:32 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.65 2007/10/26 13:24:39 joerg Exp $");
|
||||
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_ddb.h"
|
||||
|
@ -211,7 +211,7 @@ struct vm_map *phys_map = NULL;
|
|||
|
||||
extern paddr_t avail_start, avail_end;
|
||||
|
||||
void (*delay_func)(int) = i8254_delay;
|
||||
void (*delay_func)(unsigned int) = i8254_delay;
|
||||
void (*initclock_func)(void) = i8254_initclocks;
|
||||
|
||||
#ifdef MTRR
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.29 2007/10/18 15:28:34 yamt Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.30 2007/10/26 13:24:39 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -244,7 +244,7 @@ extern void cpu_signotify(struct lwp *);
|
|||
/*
|
||||
* We need a machine-independent name for this.
|
||||
*/
|
||||
extern void (*delay_func)(int);
|
||||
extern void (*delay_func)(unsigned int);
|
||||
|
||||
#define DELAY(x) (*delay_func)(x)
|
||||
#define delay(x) (*delay_func)(x)
|
||||
|
@ -288,7 +288,7 @@ void child_trampoline(void);
|
|||
/* clock.c */
|
||||
void initrtclock(u_long);
|
||||
void startrtclock(void);
|
||||
void i8254_delay(int);
|
||||
void i8254_delay(unsigned int);
|
||||
void i8254_microtime(struct timeval *);
|
||||
void i8254_initclocks(void);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.610 2007/10/18 15:28:35 yamt Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.611 2007/10/26 13:24:40 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -72,7 +72,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.610 2007/10/18 15:28:35 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.611 2007/10/26 13:24:40 joerg Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
|
@ -264,7 +264,7 @@ struct vm_map *phys_map = NULL;
|
|||
|
||||
extern paddr_t avail_start, avail_end;
|
||||
|
||||
void (*delay_func)(int) = i8254_delay;
|
||||
void (*delay_func)(unsigned int) = i8254_delay;
|
||||
void (*initclock_func)(void) = i8254_initclocks;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.148 2007/10/18 15:28:37 yamt Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.149 2007/10/26 13:24:40 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -281,7 +281,7 @@ extern void cpu_signotify(struct lwp *);
|
|||
/*
|
||||
* We need a machine-independent name for this.
|
||||
*/
|
||||
extern void (*delay_func)(int);
|
||||
extern void (*delay_func)(unsigned int);
|
||||
struct timeval;
|
||||
|
||||
#define DELAY(x) (*delay_func)(x)
|
||||
|
@ -362,7 +362,7 @@ void lwp_trampoline(void);
|
|||
/* clock.c */
|
||||
void initrtclock(u_long);
|
||||
void startrtclock(void);
|
||||
void i8254_delay(int);
|
||||
void i8254_delay(unsigned int);
|
||||
void i8254_microtime(struct timeval *);
|
||||
void i8254_initclocks(void);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock.c,v 1.11 2007/10/17 19:58:15 garbled Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.12 2007/10/26 13:24:40 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -121,7 +121,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.11 2007/10/17 19:58:15 garbled Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.12 2007/10/26 13:24:40 joerg Exp $");
|
||||
|
||||
/* #define CLOCKDEBUG */
|
||||
/* #define CLOCK_PARANOIA */
|
||||
|
@ -181,7 +181,8 @@ int clock_debug = 0;
|
|||
#define DPRINTF(arg)
|
||||
#endif
|
||||
|
||||
int gettick(void);
|
||||
/* Used by lapic.c */
|
||||
unsigned int gettick(void);
|
||||
void sysbeep(int, int);
|
||||
static void tickle_tc(void);
|
||||
|
||||
|
@ -194,7 +195,7 @@ static int cmoscheck(void);
|
|||
|
||||
static int clock_expandyear(int);
|
||||
|
||||
static inline int gettick_broken_latch(void);
|
||||
static unsigned int gettick_broken_latch(void);
|
||||
|
||||
static volatile uint32_t i8254_lastcount;
|
||||
static volatile uint32_t i8254_offset;
|
||||
|
@ -253,7 +254,7 @@ static int ticks[6];
|
|||
* machdep sets the variable 'clock_broken_latch' to indicate it.
|
||||
*/
|
||||
|
||||
int
|
||||
static unsigned int
|
||||
gettick_broken_latch(void)
|
||||
{
|
||||
u_long flags;
|
||||
|
@ -449,7 +450,7 @@ i8254_get_timecount(struct timecounter *tc)
|
|||
return (count);
|
||||
}
|
||||
|
||||
int
|
||||
unsigned int
|
||||
gettick(void)
|
||||
{
|
||||
u_long flags;
|
||||
|
@ -478,9 +479,10 @@ gettick(void)
|
|||
* Don't rely on this being particularly accurate.
|
||||
*/
|
||||
void
|
||||
i8254_delay(int n)
|
||||
i8254_delay(unsigned int n)
|
||||
{
|
||||
int delay_tick, odelay_tick;
|
||||
unsigned int cur_tick, initial_tick;
|
||||
int remaining;
|
||||
static const int delaytab[26] = {
|
||||
0, 2, 3, 4, 5, 6, 7, 9, 10, 11,
|
||||
12, 13, 15, 16, 17, 18, 19, 21, 22, 23,
|
||||
|
@ -495,49 +497,34 @@ i8254_delay(int n)
|
|||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted.
|
||||
*/
|
||||
odelay_tick = gettick();
|
||||
initial_tick = gettick();
|
||||
|
||||
if (n <= 25)
|
||||
n = delaytab[n];
|
||||
else {
|
||||
#ifdef __GNUC__
|
||||
remaining = delaytab[n];
|
||||
else if (n <= UINT_MAX / TIMER_FREQ) {
|
||||
/*
|
||||
* Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler
|
||||
* code so we can take advantage of the intermediate 64-bit
|
||||
* quantity to prevent loss of significance.
|
||||
* For unsigned arithmetic, division can be replaced with
|
||||
* multiplication with the inverse and a shift.
|
||||
*/
|
||||
int m;
|
||||
__asm volatile("mul %3"
|
||||
: "=a" (n), "=d" (m)
|
||||
: "0" (n), "r" (TIMER_FREQ));
|
||||
__asm volatile("div %4"
|
||||
: "=a" (n), "=d" (m)
|
||||
: "0" (n), "1" (m), "r" (1000000));
|
||||
#else
|
||||
/*
|
||||
* Calculate ((n * TIMER_FREQ) / 1e6) without using floating
|
||||
* point and without any avoidable overflows.
|
||||
remaining = n * TIMER_FREQ / 1000000;
|
||||
} else {
|
||||
/* This is a very long delay.
|
||||
* Being slow here doesn't matter.
|
||||
*/
|
||||
int sec = n / 1000000,
|
||||
usec = n % 1000000;
|
||||
n = sec * TIMER_FREQ +
|
||||
usec * (TIMER_FREQ / 1000000) +
|
||||
usec * ((TIMER_FREQ % 1000000) / 1000) / 1000 +
|
||||
usec * (TIMER_FREQ % 1000) / 1000000;
|
||||
#endif
|
||||
remaining = (unsigned long long) n * TIMER_FREQ / 1000000;
|
||||
}
|
||||
|
||||
while (n > 0) {
|
||||
while (remaining > 0) {
|
||||
#ifdef CLOCK_PARANOIA
|
||||
int delta;
|
||||
delay_tick = gettick();
|
||||
if (delay_tick > odelay_tick)
|
||||
delta = rtclock_tval - (delay_tick - odelay_tick);
|
||||
cur_tick = gettick();
|
||||
if (cur_tick > initial_tick)
|
||||
delta = rtclock_tval - (cur_tick - initial_tick);
|
||||
else
|
||||
delta = odelay_tick - delay_tick;
|
||||
delta = initial_tick - cur_tick;
|
||||
if (delta < 0 || delta >= rtclock_tval / 2) {
|
||||
DPRINTF(("delay: ignore ticks %.4x-%.4x",
|
||||
odelay_tick, delay_tick));
|
||||
initial_tick, cur_tick));
|
||||
if (clock_broken_latch) {
|
||||
DPRINTF((" (%.4x %.4x %.4x %.4x %.4x %.4x)\n",
|
||||
ticks[0], ticks[1], ticks[2],
|
||||
|
@ -546,15 +533,15 @@ i8254_delay(int n)
|
|||
DPRINTF(("\n"));
|
||||
}
|
||||
} else
|
||||
n -= delta;
|
||||
remaining -= delta;
|
||||
#else
|
||||
delay_tick = gettick();
|
||||
if (delay_tick > odelay_tick)
|
||||
n -= rtclock_tval - (delay_tick - odelay_tick);
|
||||
cur_tick = gettick();
|
||||
if (cur_tick > initial_tick)
|
||||
remaining -= rtclock_tval - (cur_tick - initial_tick);
|
||||
else
|
||||
n -= odelay_tick - delay_tick;
|
||||
remaining -= initial_tick - cur_tick;
|
||||
#endif
|
||||
odelay_tick = delay_tick;
|
||||
initial_tick = cur_tick;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lapic.c,v 1.24 2007/10/17 19:58:17 garbled Exp $ */
|
||||
/* $NetBSD: lapic.c,v 1.25 2007/10/26 13:24:41 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.24 2007/10/17 19:58:17 garbled Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.25 2007/10/26 13:24:41 joerg Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_mpbios.h" /* for MPDEBUG */
|
||||
|
@ -75,10 +75,11 @@ __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.24 2007/10/17 19:58:17 garbled Exp $");
|
|||
#include <machine/i82489reg.h>
|
||||
#include <machine/i82489var.h>
|
||||
|
||||
void lapic_delay(int);
|
||||
void lapic_microtime(struct timeval *);
|
||||
static u_int32_t lapic_gettick(void);
|
||||
/* Referenced from vector.S */
|
||||
void lapic_clockintr(void *, struct intrframe *);
|
||||
|
||||
static void lapic_delay(unsigned int);
|
||||
static uint32_t lapic_gettick(void);
|
||||
static void lapic_map(paddr_t);
|
||||
|
||||
static void lapic_hwmask(struct pic *, int);
|
||||
|
@ -369,7 +370,7 @@ lapic_initclocks()
|
|||
i82489_writereg (LAPIC_LVTT, LAPIC_LVTT_TM|LAPIC_TIMER_VECTOR);
|
||||
}
|
||||
|
||||
extern int gettick(void); /* XXX put in header file */
|
||||
extern unsigned int gettick(void); /* XXX put in header file */
|
||||
extern int rtclock_tval; /* XXX put in header file */
|
||||
extern void (*initclock_func)(void); /* XXX put in header file */
|
||||
|
||||
|
@ -455,7 +456,7 @@ lapic_calibrate_timer(ci)
|
|||
/*
|
||||
* Compute fixed-point ratios between cycles and
|
||||
* microseconds to avoid having to do any division
|
||||
* in lapic_delay and lapic_microtime.
|
||||
* in lapic_delay.
|
||||
*/
|
||||
|
||||
tmp = (1000000 * (u_int64_t)1<<32) / lapic_per_second;
|
||||
|
@ -490,8 +491,8 @@ lapic_calibrate_timer(ci)
|
|||
* delay for N usec.
|
||||
*/
|
||||
|
||||
void lapic_delay(usec)
|
||||
int usec;
|
||||
static void
|
||||
lapic_delay(unsigned int usec)
|
||||
{
|
||||
int32_t xtick, otick;
|
||||
int64_t deltat; /* XXX may want to be 64bit */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.44 2007/10/17 19:58:19 garbled Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.45 2007/10/26 13:24:41 joerg Exp $ */
|
||||
/* NetBSD: machdep.c,v 1.559 2004/07/22 15:12:46 mycroft Exp */
|
||||
|
||||
/*-
|
||||
|
@ -73,7 +73,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.44 2007/10/17 19:58:19 garbled Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.45 2007/10/26 13:24:41 joerg Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
|
@ -261,11 +261,11 @@ extern paddr_t avail_start, avail_end;
|
|||
extern paddr_t pmap_pa_start, pmap_pa_end;
|
||||
|
||||
#ifdef ISA_CLOCK
|
||||
void (*delay_func)(int) = i8254_delay;
|
||||
void (*delay_func)(unsigned int) = i8254_delay;
|
||||
void (*microtime_func)(struct timeval *) = i8254_microtime;
|
||||
void (*initclock_func)(void) = i8254_initclocks;
|
||||
#else
|
||||
void (*delay_func)(int) = xen_delay;
|
||||
void (*delay_func)(unsigned int) = xen_delay;
|
||||
void (*initclock_func)(void) = xen_initclocks;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.22 2007/10/17 19:58:28 garbled Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.23 2007/10/26 13:24:41 joerg Exp $ */
|
||||
/* NetBSD: cpu.h,v 1.113 2004/02/20 17:35:01 yamt Exp */
|
||||
|
||||
/*-
|
||||
|
@ -269,7 +269,7 @@ extern void cpu_signotify(struct lwp *);
|
|||
/*
|
||||
* We need a machine-independent name for this.
|
||||
*/
|
||||
extern void (*delay_func)(int);
|
||||
extern void (*delay_func)(unsigned int);
|
||||
|
||||
#define DELAY(x) (*delay_func)(x)
|
||||
#define delay(x) (*delay_func)(x)
|
||||
|
@ -351,12 +351,12 @@ void lwp_trampoline(void);
|
|||
#ifdef ISA_CLOCK
|
||||
void initrtclock(void);
|
||||
void startrtclock(void);
|
||||
void i8254_delay(int);
|
||||
void i8254_delay(unsigned int);
|
||||
void i8254_microtime(struct timeval *);
|
||||
void i8254_initclocks(void);
|
||||
#else
|
||||
void startrtclock(void);
|
||||
void xen_delay(int);
|
||||
void xen_delay(unsigned int);
|
||||
void xen_initclocks(void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock.c,v 1.40 2007/10/17 19:58:32 garbled Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.41 2007/10/26 13:24:44 joerg Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include "opt_xen.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.40 2007/10/17 19:58:32 garbled Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.41 2007/10/26 13:24:44 joerg Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -398,7 +398,7 @@ startrtclock()
|
|||
* Wait approximately `n' microseconds.
|
||||
*/
|
||||
void
|
||||
xen_delay(int n)
|
||||
xen_delay(unsigned int n)
|
||||
{
|
||||
if (n < 500000) {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue