1dnl FC_CHECK_GETTIMEOFDAY_RUNTIME(EXTRA-LIBS, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND)
2dnl
3dnl This tests whether gettimeofday works at runtime.  Here, "works"
4dnl means: time doesn't go backward and time doesn't jump forward by
5dnl a huge amount. It seems that glibc 2.3.1 is broken in this respect.
6
7AC_DEFUN([FC_CHECK_GETTIMEOFDAY_RUNTIME],
8[
9templibs="$LIBS"
10LIBS="$1 $LIBS"
11AC_RUN_IFELSE([AC_LANG_SOURCE([[
12#include <sys/time.h>
13#include <unistd.h>
14#include <stdio.h>
15#include <time.h>
16#include <stdlib.h>
17
18#define VERBOSE 0
19#define SECONDS	3
20
21int main(int argc, char **argv)
22{
23  struct timeval tv[2], start, end;
24  int calls;
25
26  if (gettimeofday(&start, NULL) == -1) {
27    return 1;
28  }
29  end = start;
30  end.tv_sec += SECONDS;
31
32  tv[0] = start;
33  tv[1] = start;
34
35  for (calls = 0;; calls++) {
36    time_t sec;
37
38    if (gettimeofday(&tv[0], NULL) == -1) {
39      return 1;
40    }
41
42    if (tv[0].tv_sec < tv[1].tv_sec) {
43#if VERBOSE
44      double diff =
45	  (tv[1].tv_sec - start.tv_sec) +
46	  ((tv[1].tv_usec - start.tv_usec) / 1e6);
47      printf("after %fs: going backward by %lds\n", diff,
48	     tv[1].tv_sec - tv[0].tv_sec);
49#endif
50      return 1;
51    }
52
53    if (tv[0].tv_sec == tv[1].tv_sec && tv[0].tv_usec < tv[1].tv_usec) {
54#if VERBOSE
55      double diff =
56	  (tv[1].tv_sec - start.tv_sec) +
57	  ((tv[1].tv_usec - start.tv_usec) / 1e6);
58      printf("after %fs: going backward by %ldus\n", diff,
59	     tv[1].tv_usec - tv[0].tv_usec);
60#endif
61      return 1;
62    }
63
64    if (tv[0].tv_sec > tv[1].tv_sec + 1) {
65#if VERBOSE
66      double diff =
67	  (tv[1].tv_sec - start.tv_sec) +
68	  ((tv[1].tv_usec - start.tv_usec) / 1e6);
69      printf("after %fs: going forward by %lds\n", diff,
70	     tv[0].tv_sec - tv[1].tv_sec);
71#endif
72      return 1;
73    }
74
75    sec = time(NULL);
76
77    if (abs(sec - tv[0].tv_sec) > 1) {
78#if VERBOSE
79      double diff =
80	  (tv[1].tv_sec - start.tv_sec) +
81	  ((tv[1].tv_usec - start.tv_usec) / 1e6);
82      printf("after %fs: time() = %ld, gettimeofday = %ld, diff = %ld\n", diff,
83	     (long)sec, (long)tv[0].tv_sec, sec - (long)tv[0].tv_sec);
84#endif
85      return 1;
86    }
87
88    if (timercmp(&tv[0], &end, >)) {
89      break;
90    }
91    tv[1] = tv[0];
92  }
93
94#if VERBOSE
95  {
96    double diff =
97	(tv[1].tv_sec - start.tv_sec) +
98	((tv[1].tv_usec - start.tv_usec) / 1e6);
99    printf("%d calls in %fs = %fus/call\n", calls, diff, 1e6 * diff / calls);
100  }
101#endif
102  return 0;
103}
104]])],[AC_MSG_RESULT(yes)
105  [$2]],[AC_MSG_RESULT(no)
106  [$3]],[AC_MSG_RESULT(unknown: cross-compiling)
107  [$3]])
108LIBS="$templibs"
109])
110