Commit a07c4054 by Janus Weil

re PR fortran/55548 (SYSTEM_CLOCK with integer(8) provides nanosecond…

re PR fortran/55548 (SYSTEM_CLOCK with integer(8) provides nanosecond resolution, but only microsecond precision (without -lrt))

2012-12-03  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/55548
	* intrinsics/system_clock.c (gf_gettime_mono): Add argument 'tck',
	which returns the clock resolution.
	(system_clock_4): Get resolution from gf_gettime_mono, but limit to
	1000/s.
	(system_clock_8): Get resolution from gf_gettime_mono.

2012-12-03  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/55548
	* intrinsic.texi (SYSTEM_CLOCK): Update documentation of SYSTEM_CLOCK.

From-SVN: r194105
parent 86035eec
2012-12-03 Janus Weil <janus@gcc.gnu.org>
PR fortran/55548
* intrinsic.texi (SYSTEM_CLOCK): Update documentation of SYSTEM_CLOCK.
2012-12-03 Tobias Burnus <burnus@net-b.de> 2012-12-03 Tobias Burnus <burnus@net-b.de>
Janus Weil <janus@gcc.gnu.org> Janus Weil <janus@gcc.gnu.org>
......
...@@ -12014,12 +12014,11 @@ nanosecond resolution. If a high resolution monotonic clock is not ...@@ -12014,12 +12014,11 @@ nanosecond resolution. If a high resolution monotonic clock is not
available, the implementation falls back to a potentially lower available, the implementation falls back to a potentially lower
resolution realtime clock. resolution realtime clock.
@var{COUNT_RATE} and @var{COUNT_MAX} vary depending on the kind of the @var{COUNT_RATE} is system dependent and can vary depending on the kind of the
arguments. For @var{kind=8} arguments, @var{COUNT} represents arguments. For @var{kind=4} arguments, @var{COUNT} usually represents
nanoseconds, and for @var{kind=4} arguments, @var{COUNT} represents milliseconds, while for @var{kind=8} arguments, @var{COUNT} typically
milliseconds. Other than the kind dependency, @var{COUNT_RATE} and represents micro- or nanoseconds. @var{COUNT_MAX} usually equals
@var{COUNT_MAX} are constant, however the particular values are @code{HUGE(COUNT_MAX)}.
specific to @command{gfortran}.
If there is no clock, @var{COUNT} is set to @code{-HUGE(COUNT)}, and If there is no clock, @var{COUNT} is set to @code{-HUGE(COUNT)}, and
@var{COUNT_RATE} and @var{COUNT_MAX} are set to zero. @var{COUNT_RATE} and @var{COUNT_MAX} are set to zero.
......
2012-12-03 Janus Weil <janus@gcc.gnu.org>
PR fortran/55548
* intrinsics/system_clock.c (gf_gettime_mono): Add argument 'tck',
which returns the clock resolution.
(system_clock_4): Get resolution from gf_gettime_mono, but limit to
1000/s.
(system_clock_8): Get resolution from gf_gettime_mono.
2012-10-28 Tobias Burnus <burnus@net-b.de> 2012-10-28 Tobias Burnus <burnus@net-b.de>
* m4/bessel.m4: Remove useless statement. * m4/bessel.m4: Remove useless statement.
......
...@@ -64,6 +64,7 @@ static int weak_gettime (clockid_t, struct timespec *) ...@@ -64,6 +64,7 @@ static int weak_gettime (clockid_t, struct timespec *)
Arguments: Arguments:
secs - OUTPUT, seconds secs - OUTPUT, seconds
nanosecs - OUTPUT, nanoseconds nanosecs - OUTPUT, nanoseconds
tk - OUTPUT, clock resolution [counts/sec]
If the target supports a monotonic clock, the OUTPUT arguments If the target supports a monotonic clock, the OUTPUT arguments
represent a monotonically incrementing clock starting from some represent a monotonically incrementing clock starting from some
...@@ -76,11 +77,12 @@ static int weak_gettime (clockid_t, struct timespec *) ...@@ -76,11 +77,12 @@ static int weak_gettime (clockid_t, struct timespec *)
is set. is set.
*/ */
static int static int
gf_gettime_mono (time_t * secs, long * nanosecs) gf_gettime_mono (time_t * secs, long * nanosecs, long * tck)
{ {
int err; int err;
#ifdef HAVE_CLOCK_GETTIME #ifdef HAVE_CLOCK_GETTIME
struct timespec ts; struct timespec ts;
*tck = 1000000000;
err = clock_gettime (GF_CLOCK_MONOTONIC, &ts); err = clock_gettime (GF_CLOCK_MONOTONIC, &ts);
*secs = ts.tv_sec; *secs = ts.tv_sec;
*nanosecs = ts.tv_nsec; *nanosecs = ts.tv_nsec;
...@@ -90,12 +92,14 @@ gf_gettime_mono (time_t * secs, long * nanosecs) ...@@ -90,12 +92,14 @@ gf_gettime_mono (time_t * secs, long * nanosecs)
if (weak_gettime) if (weak_gettime)
{ {
struct timespec ts; struct timespec ts;
*tck = 1000000000;
err = weak_gettime (GF_CLOCK_MONOTONIC, &ts); err = weak_gettime (GF_CLOCK_MONOTONIC, &ts);
*secs = ts.tv_sec; *secs = ts.tv_sec;
*nanosecs = ts.tv_nsec; *nanosecs = ts.tv_nsec;
return err; return err;
} }
#endif #endif
*tck = 1000000;
err = gf_gettime (secs, nanosecs); err = gf_gettime (secs, nanosecs);
*nanosecs *= 1000; *nanosecs *= 1000;
return err; return err;
...@@ -118,21 +122,20 @@ void ...@@ -118,21 +122,20 @@ void
system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate, system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate,
GFC_INTEGER_4 *count_max) GFC_INTEGER_4 *count_max)
{ {
#undef TCK
#define TCK 1000
GFC_INTEGER_4 cnt; GFC_INTEGER_4 cnt;
GFC_INTEGER_4 mx; GFC_INTEGER_4 mx;
time_t secs; time_t secs;
long nanosecs; long nanosecs, tck;
if (sizeof (secs) < sizeof (GFC_INTEGER_4)) if (sizeof (secs) < sizeof (GFC_INTEGER_4))
internal_error (NULL, "secs too small"); internal_error (NULL, "secs too small");
if (gf_gettime_mono (&secs, &nanosecs) == 0) if (gf_gettime_mono (&secs, &nanosecs, &tck) == 0)
{ {
GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) secs * TCK; tck = tck>1000 ? 1000 : tck;
ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK); GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) secs * tck;
ucnt += (nanosecs + 500000000 / tck) / (1000000000 / tck);
if (ucnt > GFC_INTEGER_4_HUGE) if (ucnt > GFC_INTEGER_4_HUGE)
cnt = ucnt - GFC_INTEGER_4_HUGE - 1; cnt = ucnt - GFC_INTEGER_4_HUGE - 1;
else else
...@@ -153,7 +156,7 @@ system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate, ...@@ -153,7 +156,7 @@ system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate,
if (count != NULL) if (count != NULL)
*count = cnt; *count = cnt;
if (count_rate != NULL) if (count_rate != NULL)
*count_rate = TCK; *count_rate = tck;
if (count_max != NULL) if (count_max != NULL)
*count_max = mx; *count_max = mx;
} }
...@@ -165,21 +168,19 @@ void ...@@ -165,21 +168,19 @@ void
system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate, system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate,
GFC_INTEGER_8 *count_max) GFC_INTEGER_8 *count_max)
{ {
#undef TCK
#define TCK 1000000000
GFC_INTEGER_8 cnt; GFC_INTEGER_8 cnt;
GFC_INTEGER_8 mx; GFC_INTEGER_8 mx;
time_t secs; time_t secs;
long nanosecs; long nanosecs, tck;
if (sizeof (secs) < sizeof (GFC_INTEGER_4)) if (sizeof (secs) < sizeof (GFC_INTEGER_4))
internal_error (NULL, "secs too small"); internal_error (NULL, "secs too small");
if (gf_gettime_mono (&secs, &nanosecs) == 0) if (gf_gettime_mono (&secs, &nanosecs, &tck) == 0)
{ {
GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) secs * TCK; GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) secs * tck;
ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK); ucnt += (nanosecs + 500000000 / tck) / (1000000000 / tck);
if (ucnt > GFC_INTEGER_8_HUGE) if (ucnt > GFC_INTEGER_8_HUGE)
cnt = ucnt - GFC_INTEGER_8_HUGE - 1; cnt = ucnt - GFC_INTEGER_8_HUGE - 1;
else else
...@@ -201,7 +202,7 @@ system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate, ...@@ -201,7 +202,7 @@ system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate,
if (count != NULL) if (count != NULL)
*count = cnt; *count = cnt;
if (count_rate != NULL) if (count_rate != NULL)
*count_rate = TCK; *count_rate = tck;
if (count_max != NULL) if (count_max != NULL)
*count_max = mx; *count_max = mx;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment