Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Dec 1996 19:25:16 +0900 (JST)
From:      ohashi@mickey.ai.kyutech.ac.jp (Takeshi OHASHI)
To:        current@freebsd.org
Cc:        ohashi@mickey.ai.kyutech.ac.jp
Subject:   DELAY() in clock.c
Message-ID:  <199612061025.TAA03098@atohasi.mickey.ai.kyutech.ac.jp>

next in thread | raw e-mail | index | archive | help
Hi everyone,

  I am a new subscriber of currnet, and I reported a bug of clock.c.

>Category:       i386
>Responsible:    freebsd-bugs
>Synopsis:       DELAY() won't work for fast CPUs
>Arrival-Date:   Mon Nov  4 21:00:01 PST 1996

  This problem would make hanging up the system, especially that is
a Pentium or Pentum Pro box. For example, my Pentium Pro 200 box hung
up by keybord and NIC. I reported a quick bug fix patch with it.

  We discussed the patch in freebsd-users-jp@jp.freebsd.org.
Many users said that it was a serious problem and the patch fixed it.

  We made a new patch and tested it. We want to commit it as soon as
possible. Please check the following patch for /usr/src/sys/i386/isa/clock.c.

Thank you.
--
Takeshi OHASHI, Kyushu Inst. of Tech.
ohashi@mickey.ai.kyutech.ac.jp


--- clock.c.orig	Sat Oct 26 09:11:57 1996
+++ clock.c	Mon Dec  2 22:58:36 1996
@@ -133,6 +133,8 @@
 static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
 static	u_char	rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
 
+static u_int delay_offset = 20;
+
 /* Values for timerX_state: */
 #define	RELEASED	0
 #define	RELEASE_PENDING	1
@@ -385,7 +387,7 @@
 	 * multiplications and divisions to scale the count take a while).
 	 */
 	prev_tick = getit();
-	n -= 20;
+	n = (n <= delay_offset) ? 1 : (n - delay_offset);
 	/*
 	 * Calculate (n * (timer_freq / 1e6)) without using floating point
 	 * and without any avoidable overflows.
@@ -485,6 +487,7 @@
 {
 	u_int count, prev_count, tot_count;
 	int sec, start_sec, timeout;
+	int start_tick, end_tick, delay;
 
 	printf("Calibrating clock(s) relative to mc146818A clock ... ");
 	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
@@ -564,6 +567,25 @@
 #endif
 
 	printf("i8254 clock: %u Hz\n", tot_count);
+
+	/* init delay_offset */
+	delay_offset = 0;
+	/* some machine has too small max_count */
+	delay = timer0_max_count / 10 * 1000000 / timer_freq;
+	do {
+		start_tick = getit();
+		DELAY(delay);
+		end_tick = getit();
+	} while (start_tick <= end_tick);
+	/* avoid overflow */
+	delay_offset = (start_tick - end_tick) * 1000000.0 / timer_freq - delay;
+#ifdef DELAYOFFSETDEBUG
+	printf("DELAY: %d usec\n", delay);
+	printf("DELAY offset: %u usec\n", delay_offset);
+#endif
+	if (!(0 < delay_offset || delay_offset < 20))
+		delay_offset = 20;
+
 	return (tot_count);
 
 fail:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612061025.TAA03098>