svn commit: r219646 - head/sys/x86/isa
Jung-uk Kim
jkim at FreeBSD.org
Mon Mar 14 22:05:59 UTC 2011
Author: jkim
Date: Mon Mar 14 22:05:59 2011
New Revision: 219646
URL: http://svn.freebsd.org/changeset/base/219646
Log:
When TSC is unavailable, broken or disabled and the current timecounter has
better quality than i8254 timer, use it for DELAY(9).
Modified:
head/sys/x86/isa/clock.c
Modified: head/sys/x86/isa/clock.c
==============================================================================
--- head/sys/x86/isa/clock.c Mon Mar 14 19:31:43 2011 (r219645)
+++ head/sys/x86/isa/clock.c Mon Mar 14 22:05:59 2011 (r219646)
@@ -245,6 +245,42 @@ getit(void)
return ((high << 8) | low);
}
+static __inline void
+delay_tsc(int n)
+{
+ uint64_t start, end, now;
+
+ sched_pin();
+ start = rdtsc();
+ end = start + (tsc_freq * n) / 1000000;
+ do {
+ cpu_spinwait();
+ now = rdtsc();
+ } while (now < end || (now > start && end < start));
+ sched_unpin();
+}
+
+static __inline void
+delay_timecounter(struct timecounter *tc, int n)
+{
+ uint64_t end, now;
+ u_int last, mask, u;
+
+ mask = tc->tc_counter_mask;
+ last = tc->tc_get_timecount(tc) & mask;
+ end = tc->tc_frequency * n / 1000000;
+ now = 0;
+ do {
+ cpu_spinwait();
+ u = tc->tc_get_timecount(tc) & mask;
+ if (u < last)
+ now += mask - last + u + 1;
+ else
+ now += u - last;
+ last = u;
+ } while (now < end);
+}
+
/*
* Wait "n" microseconds.
* Relies on timer 1 counting down from (i8254_freq / hz)
@@ -253,6 +289,7 @@ getit(void)
void
DELAY(int n)
{
+ struct timecounter *tc;
int delta, prev_tick, tick, ticks_left;
#ifdef DELAYDEBUG
@@ -262,16 +299,12 @@ DELAY(int n)
#endif
if (tsc_freq != 0) {
- uint64_t start, end, now;
-
- sched_pin();
- start = rdtsc();
- end = start + (tsc_freq * n) / 1000000;
- do {
- cpu_spinwait();
- now = rdtsc();
- } while (now < end || (now > start && end < start));
- sched_unpin();
+ delay_tsc(n);
+ return;
+ }
+ tc = timecounter;
+ if (tc->tc_quality > 0) {
+ delay_timecounter(tc, n);
return;
}
#ifdef DELAYDEBUG
More information about the svn-src-all
mailing list