Xref: utzoo comp.os.minix:5760 comp.sys.atari.st:16216 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!uxc!deimos.cis.ksu.edu!rutgers!att!cbnewsl!mjs From: mjs@cbnewsl.ATT.COM (Mike Scheutzow) Newsgroups: comp.os.minix,comp.sys.atari.st Subject: Re: Real time clock from MINIX? Message-ID: <572@cbnewsl.ATT.COM> Date: 8 May 89 18:02:30 GMT References: <2398@brahma.cs.hw.ac.uk> <18018@cup.portal.com> Distribution: usa Organization: AT&T Lines: 98 > Article 1432 of comp.os.minix: > I got a question... > > is minix's sleep() broken... > Then test2 will terminate after looping few times, but > test1 will never wake up... > bruce deadhead@cup.portal.com There was a bug in sleep() for minix-pc v1.2, and it may be in your system as well. Chip Roberson posted the problem and the fix a few months ago; it is appended. I make no claims about the accuracy of this information. Mike S. att!chnewsl!mjs -------------------------------------------------------------------- xFrom att!rutgers!rochester!udel!mmdf Thu Dec 15 04:28:03 1988 xPath: whuts!att!rutgers!rochester!udel!mmdf xFrom: csrobe@cs.wm.edu (Chip Roberson) xNewsgroups: comp.os.minix xSubject: sleep() [SIGALRM] bug in 1.2 xMessage-ID: <5983@louie.udel.EDU> xDate: 15 Dec 88 09:28:03 GMT xSender: usenet@udel.EDU xLines: 71 There is a bug in the 1.2 Version of PC Minix (that I have). You can determine if you have the bug by running the following code: if (fork() == 0) while (1) { putchar('c'); fflush(stdout); sleep(1); } else while (1) { putchar('p'); fflush(stdout); sleep(2); } if the ONLY output you see is something like: cpc then you have the same bug. NB: This bug will effectively kill /etc/update by breaking its sleep/wake-up loop! The problem is in mm/signal.c/check_sig at lines 6824-6842, where mm searches "through the proc table for processes to signal". for(...) { ... if (proc_id > 0 && proc_id != rmp->mp_pid) send_sig = FALSE; ... /* SIGALARM is a little special. When a process exits, a clock signal * can arrive just as the timer is being turned off. Also, turn off * ALARM_ON bit when timer goes off to keep it accurate. */ if (sig_nr == SIGALRM) { if ( (rmp->mp_flags & ALARM_ON) == 0) continue; rmp->mp_flags &= ~ALARM_ON; } if (send_sig == FALSE || rmp->mp_ignore & mask) continue; ... } The problem occurs when there are two alarms pending at the same time and an alarm goes off for the process deeper/later in the process table. The first check, determines that the signal is not for this process (proc_id != rmp->mp_pid) and sets a flag (send_sig = FALSE). Later on, it checks to see if this is an ALARM signal. If it is, then it makes sure that the process is still there and that it is still waiting for a signal. [BUT, at this point, we know that this process is not the correct process.] Well, if mm sees that this process has it's ALARM bit on (and /etc/update always will, and it will always be lower than any other user process!) it will turn off the ALARM_ON bit thinking that this process is about to be awoken. Well the last line, above, realizes that the signal really isn't for this process and goes to the next iteration of the for-loop. ERGO: an ALARM signal for process N will clear all outstanding ALARMs for any process i, INIT_PROC_NR < i < N. The fix is to move if (send_sig == FALSE || rmp->mp_ignore & mask) continue; before if (sig_nr == SIGALRM) { I would have sent diffs but that was just too much trouble to get them to a networked machine. cheers, -c ------------------------------------------------------------------------- Chip Roberson ARPANET: csrobe@cs.wm.edu Dept of Comp. Sci. csrobe@icase.edu College of William and Mary BITNET: #csrobe@wmmvs.bitnet Williamsburg, VA 23185 UUCP: ...!uunet!pyrdc!gmu90x!wmcs!csrobe -------------------------------------------------------------------------