1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
$NetBSD: patch-ab,v 1.3 2004/07/10 21:27:46 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);
}
|