$NetBSD: patch-ab,v 1.2 2001/02/06 18:13:52 wiz Exp $ --- ./lib/bsd/mstime.c.orig Wed Oct 30 12:39:40 1996 +++ ./lib/bsd/mstime.c Thu Jan 25 07:08:41 2001 @@ -12,11 +12,56 @@ * (and you don't need to know HZ) */ +/* Added by refling@comet.lbl.gov to compensate for the fact that the usec + value can go backwards within the same sec on NetBSD. Problem has been + noted on sparc and i386. It really only appears in the test routine + where times are differenced, causing negative numbers to be generated. + This WILL cause the build to fail consistently on my sparc LX, but not + on the i386, even though the problem can be demonstrated there. See + NetBSD PR bin/10201. + + The simple solution here is to have a persistent variable, and if the + usec value returned from getrusage() is LESS than the previous one + (stored in the persistent variable), use the previous one. This is + only when the second counter is the same between the previous and + current usec. This will make time stand still, but at least it + won't go backwards! + + This could also be added to the definition of the NetBSD getrusage() + function to prevent it from returning bogus values in the first place, + if the real cause of the problem can't be tracked down. + + Note that the patch to snobol4 (in this file) will not need to be + changed even if/when getrusage() is ultimately fixed. The only expense + is a few extra numerical comparisons. Typically, one doesn't take time + measurements too often. */ + +static long prev_sec = 0; +static long prev_usec = 0; + int_t mstime() { struct rusage ru; + long cur_usec, cur_sec; getrusage( RUSAGE_SELF, &ru ); /* XXX check return? */ - return(ru.ru_utime.tv_sec * 1000 + - ru.ru_utime.tv_usec / 1000); + cur_usec = ru.ru_utime.tv_usec; + cur_sec = ru.ru_utime.tv_sec; + if (prev_usec > cur_usec && prev_sec == cur_sec) { + cur_usec = prev_usec; +// prev_sec = cur_sec; /* this is redundant in this case, since == */ +// prev_usec = cur_usec; /* this is also redundant */ +// system("echo a >> /tmp/caught_problem"); + } + else { + prev_sec = cur_sec; + prev_usec = cur_usec; + } + return(cur_sec * 1000 + + cur_usec / 1000); + +// this is what it was.... +// getrusage( RUSAGE_SELF, &ru ); /* XXX check return? */ +// return(ru.ru_utime.tv_sec * 1000 + +// ru.ru_utime.tv_usec / 1000); }