summaryrefslogtreecommitdiff
path: root/lang/snobol/patches/patch-ab
blob: 3b0e61a5a3a2754ce8c115bef2367a9184ebb1fa (plain)
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.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);
 }