diff options
author | peter <peter@FreeBSD.org> | 2005-12-12 22:27:07 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2005-12-12 22:27:07 +0000 |
commit | 5aa0590aa8779193961836d3b206d315ce891ae8 (patch) | |
tree | 859c6c561f045147c3e4e7ae8187cb7c0dc6a37a /sys/amd64/isa/clock.c | |
parent | 8aa9fc9c151a7b7a6aa913be91fae2dca213edc4 (diff) | |
download | FreeBSD-src-5aa0590aa8779193961836d3b206d315ce891ae8.zip FreeBSD-src-5aa0590aa8779193961836d3b206d315ce891ae8.tar.gz |
For the amd64 platform, we can depend on the TSC being present. This patch
changes DELAY to use the TSC once it has been calibrated. This does NOT
use the TSC for long-term timekeeping. It only uses it to bound the
DELAY() spinloop. This should not be affected by the Athlon64 X2 TSC
quirks because the cpu is not halted while we use DELAY().
Diffstat (limited to 'sys/amd64/isa/clock.c')
-rw-r--r-- | sys/amd64/isa/clock.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index e875610..9918a66 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/limits.h> #include <sys/module.h> +#include <sys/sched.h> #include <sys/sysctl.h> #include <sys/cons.h> #include <sys/power.h> @@ -269,7 +270,21 @@ DELAY(int n) int getit_calls = 1; int n1; static int state = 0; +#endif + + if (tsc_freq != 0 && !tsc_is_broken) { + uint64_t start, end, now; + sched_pin(); + start = rdtsc(); + end = start + (tsc_freq * n) / 1000000; + do { + now = rdtsc(); + } while (now < end || (now > start && end < start)); + sched_unpin(); + return; + } +#ifdef DELAYDEBUG if (state == 0) { state = 1; for (n1 = 1; n1 <= 10000000; n1 *= 10) |