diff options
author | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-05 16:22:04 +0000 |
---|---|---|
committer | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-05 16:22:04 +0000 |
commit | f2c8d53a5fdde4f206589a0516e58927d88dd750 (patch) | |
tree | 8f4de5377ee7b6e94eba0353814a02bb30e8f523 /libgfortran/intrinsics/system_clock.c | |
parent | 51a13f08e2afea8c46cc1977b86dd0964da07bd5 (diff) | |
download | gcc-f2c8d53a5fdde4f206589a0516e58927d88dd750.tar.gz |
PR 47571 Fix HPUX bootstrap regression, cleanup
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169852 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/intrinsics/system_clock.c')
-rw-r--r-- | libgfortran/intrinsics/system_clock.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/libgfortran/intrinsics/system_clock.c b/libgfortran/intrinsics/system_clock.c index 37155628d53..3a44dd9666b 100644 --- a/libgfortran/intrinsics/system_clock.c +++ b/libgfortran/intrinsics/system_clock.c @@ -29,6 +29,75 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "time_1.h" +#ifdef HAVE_CLOCK_GETTIME +/* POSIX states that CLOCK_REALTIME must be present if clock_gettime + is available, others are optional. */ +#ifdef CLOCK_MONOTONIC +#define GF_CLOCK_MONOTONIC CLOCK_MONOTONIC +#else +#define GF_CLOCK_MONOTONIC 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. + + Some targets don't support weak undefined references; on these + GTHREAD_USE_WEAK is 0. So we need to define it to 1 on other + targets. */ +#ifndef GTHREAD_USE_WEAK +#define GTHREAD_USE_WEAK 1 +#endif + +#if SUPPORTS_WEAK && GTHREAD_USE_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 + + +/* High resolution monotonic clock, falling back to the realtime clock + if the target does not support such a clock. + + Arguments: + secs - OUTPUT, seconds + nanosecs - OUTPUT, nanoseconds + + If the target supports a monotonic clock, the OUTPUT arguments + represent a monotonically incrementing clock starting from some + unspecified time in the past. + + If a monotonic clock is not available, falls back to the realtime + clock which is not monotonic. + + Return value: 0 for success, -1 for error. In case of error, errno + is set. +*/ +static inline int +gf_gettime_mono (time_t * secs, long * nanosecs) +{ + int err; +#ifdef HAVE_CLOCK_GETTIME + if (weak_gettime) + { + struct timespec ts; + err = weak_gettime (GF_CLOCK_MONOTONIC, &ts); + *secs = ts.tv_sec; + *nanosecs = ts.tv_nsec; + return err; + } +#endif + err = gf_gettime (secs, nanosecs); + *nanosecs *= 1000; + return err; +} + extern void system_clock_4 (GFC_INTEGER_4 *, GFC_INTEGER_4 *, GFC_INTEGER_4 *); export_proto(system_clock_4); @@ -56,7 +125,7 @@ system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate, if (sizeof (secs) < sizeof (GFC_INTEGER_4)) internal_error (NULL, "secs too small"); - if (gf_gettime (GF_CLOCK_MONOTONIC, &secs, &nanosecs) == 0) + if (gf_gettime_mono (&secs, &nanosecs) == 0) { GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) secs * TCK; ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK); @@ -103,7 +172,7 @@ system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate, if (sizeof (secs) < sizeof (GFC_INTEGER_4)) internal_error (NULL, "secs too small"); - if (gf_gettime (GF_CLOCK_MONOTONIC, &secs, &nanosecs) == 0) + if (gf_gettime_mono (&secs, &nanosecs) == 0) { GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) secs * TCK; ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK); |