i386/70610: [patch] spkr(4): hardcoded assumption HZ == 100

dada at sbox.tugraz.at dada at sbox.tugraz.at
Wed Aug 18 00:40:18 PDT 2004


>Number:         70610
>Category:       i386
>Synopsis:       [patch] spkr(4): hardcoded assumption HZ == 100
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 18 07:40:16 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Martin Kammerhofer
>Release:        FreeBSD 4.10-RELEASE-p2 i386
>Organization:
Graz UNI
>Environment:
System: FreeBSD Martin.liebt.Susi 4.10-RELEASE-p2 FreeBSD 4.10-RELEASE-p2 #1: Mon Aug 16 14:26:52 CEST 2004 toor at Martin.liebt.Susi:/mnt/redhat/freebsd/usr/src/sys/compile/GEIDORF4 i386
>Description:
The spkr(4) pseudo-device driver is documented to accept tone
durations in units of 1/100ths of a second. (Cf. spkr(4) and
/usr/include/machine/speaker.h.) However the driver is implemented to
take units of 1/HZ seconds. This mismatch causes timing errors in the
HZ != 100 case.
>How-To-Repeat:
Run a kernel with the speaker(4) pseudo-device and e.g. HZ=400.
Compare times of e.g.:
time /usr/games/morse -p </etc/motd
time /usr/games/morse -d /dev/cuaa0 </etc/motd
>Fix:
--- spkr.c.orig	Wed Jun 16 11:47:08 2004
+++ spkr.c	Mon Aug 16 16:01:22 2004
@@ -91,18 +91,18 @@
 #define SPKRPRI PSOCK
 static char endtone, endrest;
 
-static void tone(unsigned int thz, unsigned int ticks);
-static void rest(int ticks);
+static void tone(unsigned int thz, unsigned int centisecs);
+static void rest(int centisecs);
 static void playinit(void);
 static void playtone(int pitch, int value, int sustain);
 static void playstring(char *cp, size_t slen);
 
-/* emit tone of frequency thz for given number of ticks */
+/* emit tone of frequency thz for given number of centisecs */
 static void
-tone(thz, ticks)
-	unsigned int thz, ticks;
+tone(thz, centisecs)
+	unsigned int thz, centisecs;
 {
-    unsigned int divisor;
+    unsigned int divisor, ticks;
     int sps;
 
     if (thz <= 0)
@@ -111,7 +111,7 @@
     divisor = timer_freq / thz;
 
 #ifdef DEBUG
-    (void) printf("tone: thz=%d ticks=%d\n", thz, ticks);
+    (void) printf("tone: thz=%d centisecs=%d\n", thz, centisecs);
 #endif /* DEBUG */
 
     /* set timer to generate clicks at given frequency in Hertz */
@@ -135,6 +135,7 @@
      * This is so other processes can execute while the tone is being
      * emitted.
      */
+    ticks = centisecs * hz / 100;
     if (ticks > 0)
 	tsleep(&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
     SPEAKER_OFF;
@@ -143,19 +144,22 @@
     splx(sps);
 }
 
-/* rest for given number of ticks */
+/* rest for given number of centisecs */
 static void
-rest(ticks)
-	int	ticks;
+rest(centisecs)
+	int	centisecs;
 {
+    int ticks;
+
     /*
      * Set timeout to endrest function, then give up the timeslice.
      * This is so other processes can execute while the rest is being
      * waited out.
      */
 #ifdef DEBUG
-    (void) printf("rest: %d\n", ticks);
+    (void) printf("rest: %d\n", centisecs);
 #endif /* DEBUG */
+    ticks = centisecs * hz / 100;
     if (ticks > 0)
 	tsleep(&endrest, SPKRPRI | PCATCH, "spkrrs", ticks);
 }

--=_21aj2zn430zo--

>Release-Note:
>Audit-Trail:
>Unformatted:
 This message is in MIME format.
 
 --=_21aj2zn430zo
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Disposition: inline
 Content-Transfer-Encoding: 7bit
 
 
 --=_21aj2zn430zo
 Content-Type: text/plain; charset=UTF-8; name="spkr.pr"
 Content-Disposition: inline; filename="spkr.pr"
 Content-Transfer-Encoding: 7bit
 


More information about the freebsd-i386 mailing list