As usual with UNIX systems, unfortunately no single way is
available for all systems. */
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# ifdef HAVE_TIME_H
-# include <time.h>
-# endif
-# endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
#endif
+#include <time.h>
+
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#endif /* !HAVE_GETRUSAGE || !HAVE_SYS_RESOURCE_H */
-#if defined (__GNUC__) && (__GNUC__ >= 3)
-# define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
-#else
-# define ATTRIBUTE_ALWAYS_INLINE
+/* If the re-entrant version of localtime is not available, provide a
+ fallback implementation. On some targets where the _r version is
+ not available, localtime uses thread-local storage so it's
+ threadsafe. */
+
+#ifndef HAVE_LOCALTIME_R
+/* If _POSIX is defined localtime_r gets defined by mingw-w64 headers. */
+#ifdef localtime_r
+#undef localtime_r
+#endif
+
+static inline struct tm *
+localtime_r (const time_t * timep, struct tm * result)
+{
+ *result = *localtime (timep);
+ return result;
+}
#endif
-static inline int gf_cputime (long *, long *, long *, long *) ATTRIBUTE_ALWAYS_INLINE;
/* Helper function for the actual implementation of the DTIME, ETIME and
CPU_TIME intrinsics. Returns 0 for success or -1 if no
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-static int
+static inline int
gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
{
union {
clock_t err;
err = times (&buf);
*user_sec = buf.tms_utime / HZ;
- *user_usec = buf.tms_utime % HZ * (1000000 / HZ);
+ *user_usec = buf.tms_utime % HZ * (1000000. / HZ);
*system_sec = buf.tms_stime / HZ;
- *system_usec = buf.tms_stime % HZ * (1000000 / HZ);
+ *system_usec = buf.tms_stime % HZ * (1000000. / HZ);
if ((err == (clock_t) -1) && errno != 0)
return -1;
return 0;
#else
-
- /* We have nothing to go on. Return -1. */
- *user_sec = *system_sec = 0;
- *user_usec = *system_usec = 0;
- errno = ENOSYS;
- return -1;
+ clock_t c = clock ();
+ *user_sec = c / CLOCKS_PER_SEC;
+ *user_usec = c % CLOCKS_PER_SEC * (1000000. / CLOCKS_PER_SEC);
+ *system_sec = *system_usec = 0;
+ if (c == (clock_t) -1)
+ return -1;
+ return 0;
#endif
}
#endif
-/* POSIX states that CLOCK_REALTIME must be present if clock_gettime
- is available, others are optional. */
-#ifdef CLOCK_REALTIME
-#define GF_CLOCK_REALTIME CLOCK_REALTIME
-#else
-#define GF_CLOCK_REALTIME 0
-#endif
+/* Realtime clock with microsecond resolution, falling back to less
+ precise functions if the target does not support gettimeofday().
-#ifdef CLOCK_MONOTONIC
-#define GF_CLOCK_MONOTONIC CLOCK_MONOTONIC
-#else
-#define GF_CLOCK_MONOTONIC GF_CLOCK_REALTIME
-#endif
-
-/* Weakref trickery for clock_gettime(). On Glibc, clock_gettime()
- requires us to link in librt, which also pulls in libpthread. In
- order to avoid this by default, only call clock_gettime() through a
- weak reference. */
-#ifdef HAVE_CLOCK_GETTIME
-#ifdef SUPPORTS_WEAK
-static int weak_gettime (clockid_t, struct timespec *)
- __attribute__((__weakref__("clock_gettime")));
-#else
-static inline int weak_gettime (clockid_t clk_id, struct timespec *res)
-{
- return clock_gettime (clk_id, res);
-}
-#endif
-#endif
-
-/* Arguments:
- clock_id - INPUT, must be either GF_CLOCK_REALTIME or GF_CLOCK_MONOTONIC
+ Arguments:
secs - OUTPUT, seconds
- nanosecs - OUTPUT, OPTIONAL, nanoseconds
+ usecs - OUTPUT, microseconds
- If clock_id equals GF_CLOCK_REALTIME, the OUTPUT arguments shall be
- the number of seconds and nanoseconds since the Epoch. If clock_id
- equals GF_CLOCK_MONOTONIC, and if the target supports it, the
- OUTPUT arguments represent a monotonically incrementing clock
- starting from some unspecified time in the past.
+ The OUTPUT arguments shall represent the number of seconds and
+ nanoseconds since the Epoch.
Return value: 0 for success, -1 for error. In case of error, errno
is set.
*/
static inline int
-gf_gettime (int clock_id __attribute__((unused)), time_t * secs,
- long * nanosecs)
+gf_gettime (time_t * secs, long * usecs)
{
-#ifdef HAVE_CLOCK_GETTIME
- if (weak_gettime)
- {
- struct timespec ts;
- int err;
- err = weak_gettime (clock_id, &ts);
- *secs = ts.tv_sec;
- if (nanosecs)
- *nanosecs = ts.tv_nsec;
- return err;
- }
-#endif
#ifdef HAVE_GETTIMEOFDAY
struct timeval tv;
int err;
err = gettimeofday (&tv, NULL);
*secs = tv.tv_sec;
- if (nanosecs)
- *nanosecs = tv.tv_usec * 1000;
+ *usecs = tv.tv_usec;
return err;
-#elif HAVE_TIME
- time_t t, t2;
- t = time (&t2);
- *secs = t2;
- if (nanosecs)
- *nanosecs = 0;
+#else
+ time_t t = time (NULL);
+ *secs = t;
+ *usecs = 0;
if (t == ((time_t)-1))
return -1;
return 0;
-#else
- *secs = 0;
- if (nanosecs)
- *nanosecs = 0;
- errno = ENOSYS;
- return -1;
#endif
}