Sync from coreutils.
[gnulib.git] / lib / gethrxtime.c
1 /* gethrxtime -- get high resolution real time
2
3    Copyright (C) 2005 Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2, or (at your option)
8    any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19 /* Written by Paul Eggert.  */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include "gethrxtime.h"
26
27 #include <sys/types.h>
28 #if TIME_WITH_SYS_TIME
29 # include <sys/time.h>
30 # include <time.h>
31 #else
32 # if HAVE_SYS_TIME_H
33 #  include <sys/time.h>
34 # else
35 #  include <time.h>
36 # endif
37 #endif
38
39 /* Get the time of a high-resolution clock, preferably one that is not
40    subject to resetting or drifting.  */
41
42 xtime_t
43 gethrxtime (void)
44 {
45 #if HAVE_NANOUPTIME
46   {
47     struct timespec ts;
48     nanouptime (&ts);
49     return xtime_make (ts.tv_sec, ts.tv_nsec);
50   }
51 #else
52
53 # if defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME
54   {
55     struct timespec ts;
56     if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
57       return xtime_make (ts.tv_sec, ts.tv_nsec);
58   }
59 # endif
60
61 # if HAVE_MICROUPTIME
62   {
63     struct timeval tv;
64     microuptime (&tv);
65     return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
66   }
67
68   /* No monotonically increasing clocks are available; fall back on a
69      clock that might jump backwards, since it's the best we can do.  */
70 # elif HAVE_GETTIMEOFDAY && XTIME_PRECISION != 1
71   {
72     struct timeval tv;
73     gettimeofday (&tv, NULL);
74     return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
75   }
76 # else
77   return xtime_make (time (NULL), 0);
78 # endif
79 #endif
80 }