mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-25 11:54:01 +08:00
Use clock_gettime in libgfortran timing intrinsics, cleanup
From-SVN: r169449
This commit is contained in:
parent
e1bcd685a2
commit
b6e7a3d1f9
@ -1,3 +1,19 @@
|
||||
2011-01-31 Janne Blomqvist <jb@gcc.gnu.org>
|
||||
|
||||
* configure.ac: Check for clock_gettime().
|
||||
* configure: Regenerated.
|
||||
* config.h.in: Regenerated.
|
||||
* intrinsics/time_1.h (__time_1): Rename to gf_cputime, add
|
||||
times() fallback.
|
||||
(gf_gettime): New function.
|
||||
* intrinsics/cpu_time.c (__cpu_time_1): Update to call gf_cputime.
|
||||
* intrinsics/date_and_time.c (date_and_time): Use gf_gettime.
|
||||
* intrinsics/dtime.c (dtime_sub): Use gf_cputime.
|
||||
* intrinsics/etime.c (etime_sub): Use gf_cputime.
|
||||
* intrinsics/system_clock.c (system_clock_4): Use gf_gettime.
|
||||
(system_clock_8): Use gf_gettime, increase count rate to allow
|
||||
nanosecond precision, remove overflow prone branch.
|
||||
|
||||
2011-01-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR libgfortran/47434
|
||||
|
@ -207,6 +207,9 @@
|
||||
/* Define to 1 if you have the `clock' function. */
|
||||
#undef HAVE_CLOCK
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* libm includes clog */
|
||||
#undef HAVE_CLOG
|
||||
|
||||
|
63
libgfortran/configure
vendored
63
libgfortran/configure
vendored
@ -16380,6 +16380,17 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in clock_gettime
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
|
||||
if test "x$ac_cv_func_clock_gettime" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# Check for glibc backtrace functions
|
||||
for ac_func in backtrace backtrace_symbols
|
||||
@ -25249,6 +25260,58 @@ $as_echo "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h
|
||||
fi
|
||||
|
||||
|
||||
# At least for glibc, clock_gettime is in librt. But don't pull that
|
||||
# in if it still doesn't give us the function we want.
|
||||
# This test is copied from libgomp.
|
||||
if test $ac_cv_func_clock_gettime = no; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
|
||||
$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
|
||||
if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lrt $LIBS"
|
||||
if test x$gcc_no_link = xyes; then
|
||||
as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
|
||||
fi
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char clock_gettime ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return clock_gettime ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_rt_clock_gettime=yes
|
||||
else
|
||||
ac_cv_lib_rt_clock_gettime=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
|
||||
$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
|
||||
if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then :
|
||||
LIBS="-lrt $LIBS"
|
||||
|
||||
$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Check for SysV fpsetmask
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fpsetmask is present" >&5
|
||||
|
@ -252,6 +252,7 @@ AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock access fork execl)
|
||||
AC_CHECK_FUNCS(wait setmode execvp pipe dup2 close fdopen strcasestr getrlimit)
|
||||
AC_CHECK_FUNCS(gettimeofday stat fstat lstat getpwuid vsnprintf dup getcwd)
|
||||
AC_CHECK_FUNCS(localtime_r gmtime_r strerror_r getpwuid_r ttyname_r ctime_r)
|
||||
AC_CHECK_FUNCS(clock_gettime)
|
||||
|
||||
# Check for glibc backtrace functions
|
||||
AC_CHECK_FUNCS(backtrace backtrace_symbols)
|
||||
@ -483,6 +484,16 @@ LIBGFOR_CHECK_FLOAT128
|
||||
# Check for GNU libc feenableexcept
|
||||
AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
|
||||
|
||||
# At least for glibc, clock_gettime is in librt. But don't pull that
|
||||
# in if it still doesn't give us the function we want.
|
||||
# This test is copied from libgomp.
|
||||
if test $ac_cv_func_clock_gettime = no; then
|
||||
AC_CHECK_LIB(rt, clock_gettime,
|
||||
[LIBS="-lrt $LIBS"
|
||||
AC_DEFINE(HAVE_CLOCK_GETTIME, 1,
|
||||
[Define to 1 if you have the `clock_gettime' function.])])
|
||||
fi
|
||||
|
||||
# Check for SysV fpsetmask
|
||||
LIBGFOR_CHECK_FPSETMASK
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Implementation of the CPU_TIME intrinsic.
|
||||
Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Fortran 95 runtime library (libgfortran).
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
|
||||
Libgfortran is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
@ -25,49 +25,23 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#include "libgfortran.h"
|
||||
#include "time_1.h"
|
||||
|
||||
/* The most accurate way to get the CPU time is getrusage ().
|
||||
If we have times(), that's good enough, too. */
|
||||
#if !defined (HAVE_GETRUSAGE) || !defined (HAVE_SYS_RESOURCE_H)
|
||||
/* For times(), we _must_ know the number of clock ticks per second. */
|
||||
# if defined (HAVE_TIMES) && (defined (HZ) || defined (_SC_CLK_TCK) || defined (CLK_TCK))
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# if defined (HAVE_SYS_TIMES_H)
|
||||
# include <sys/times.h>
|
||||
# endif
|
||||
# ifndef HZ
|
||||
# if defined _SC_CLK_TCK
|
||||
# define HZ sysconf(_SC_CLK_TCK)
|
||||
# else
|
||||
# define HZ CLK_TCK
|
||||
# endif
|
||||
# endif
|
||||
# endif /* HAVE_TIMES etc. */
|
||||
#endif /* !HAVE_GETRUSAGE || !HAVE_SYS_RESOURCE_H */
|
||||
|
||||
static inline void __cpu_time_1 (long *, long *) ATTRIBUTE_ALWAYS_INLINE;
|
||||
|
||||
static inline void
|
||||
__cpu_time_1 (long *sec, long *usec)
|
||||
{
|
||||
#if defined(__MINGW32__) || defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
|
||||
long user_sec, user_usec, system_sec, system_usec;
|
||||
__time_1 (&user_sec, &user_usec, &system_sec, &system_usec);
|
||||
*sec = user_sec + system_sec;
|
||||
*usec = user_usec + system_usec;
|
||||
#else /* ! HAVE_GETRUSAGE || ! HAVE_SYS_RESOURCE_H */
|
||||
#ifdef HAVE_TIMES
|
||||
struct tms buf;
|
||||
times (&buf);
|
||||
*sec = 0;
|
||||
*usec = (buf.tms_utime + buf.tms_stime) * (1000000 / HZ);
|
||||
#else /* ! HAVE_TIMES */
|
||||
/* We have nothing to go on. Return -1. */
|
||||
*sec = -1;
|
||||
*usec = 0;
|
||||
#endif /* HAVE_TIMES */
|
||||
#endif /* __MINGW32__ || HAVE_GETRUSAGE */
|
||||
if (gf_cputime (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
|
||||
{
|
||||
*sec = user_sec + system_sec;
|
||||
*usec = user_usec + system_usec;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sec = -1;
|
||||
*usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Implementation of the DATE_AND_TIME intrinsic.
|
||||
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
|
||||
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Steven Bosscher.
|
||||
|
||||
@ -29,21 +29,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef HAVE_NO_DATE_TIME
|
||||
#if 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>
|
||||
# else
|
||||
# define HAVE_NO_DATE_TIME
|
||||
# endif /* HAVE_TIME_H */
|
||||
# endif /* HAVE_SYS_TIME_H */
|
||||
#endif /* TIME_WITH_SYS_TIME */
|
||||
#include "time_1.h"
|
||||
|
||||
#ifndef abs
|
||||
#define abs(x) ((x)>=0 ? (x) : -(x))
|
||||
@ -176,28 +162,12 @@ date_and_time (char *__date, char *__time, char *__zone,
|
||||
struct tm local_time;
|
||||
struct tm UTC_time;
|
||||
|
||||
#if HAVE_GETTIMEOFDAY
|
||||
{
|
||||
struct timeval tp;
|
||||
long nanosecs;
|
||||
|
||||
if (!gettimeofday (&tp, NULL))
|
||||
{
|
||||
lt = tp.tv_sec;
|
||||
values[7] = tp.tv_usec / 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
lt = time (NULL);
|
||||
values[7] = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
lt = time (NULL);
|
||||
values[7] = 0;
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
if (lt != (time_t) -1)
|
||||
if (!gf_gettime(GF_CLOCK_REALTIME, <, &nanosecs))
|
||||
{
|
||||
values[7] = nanosecs / 1000000;
|
||||
|
||||
localtime_r (<, &local_time);
|
||||
gmtime_r (<, &UTC_time);
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* Implementation of the dtime intrinsic.
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2009, 2011 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Fortran 95 runtime library (libgfortran).
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
|
||||
Libgfortran is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
@ -47,7 +48,7 @@ dtime_sub (gfc_array_r4 *t, GFC_REAL_4 *result)
|
||||
runtime_error ("Insufficient number of elements in TARRAY.");
|
||||
|
||||
__gthread_mutex_lock (&dtime_update_lock);
|
||||
if (__time_1 (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
|
||||
if (gf_cputime (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
|
||||
{
|
||||
tu = (GFC_REAL_4) ((user_sec - us) + 1.e-6 * (user_usec - uu));
|
||||
ts = (GFC_REAL_4) ((system_sec - ss) + 1.e-6 * (system_usec - su));
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* Implementation of the ETIME intrinsic.
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2009, 2011 Free Software
|
||||
Foundation, Inc.
|
||||
Contributed by Steven G. Kargl <kargls@comcast.net>.
|
||||
|
||||
This file is part of the GNU Fortran 95 runtime library (libgfortran).
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
|
||||
Libgfortran is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
@ -38,7 +39,7 @@ etime_sub (gfc_array_r4 *t, GFC_REAL_4 *result)
|
||||
if (((GFC_DESCRIPTOR_EXTENT(t,0))) < 2)
|
||||
runtime_error ("Insufficient number of elements in TARRAY.");
|
||||
|
||||
if (__time_1 (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
|
||||
if (gf_cputime (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
|
||||
{
|
||||
tu = (GFC_REAL_4)(user_sec + 1.e-6 * user_usec);
|
||||
ts = (GFC_REAL_4)(system_sec + 1.e-6 * system_usec);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Implementation of the SYSTEM_CLOCK intrinsic.
|
||||
Copyright (C) 2004, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2007, 2009, 2010, 2011 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
|
||||
@ -26,15 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
|
||||
# include <sys/time.h>
|
||||
#elif defined(HAVE_TIME_H)
|
||||
# include <time.h>
|
||||
# define TCK 1
|
||||
#else
|
||||
#define TCK 0
|
||||
#endif
|
||||
|
||||
#include "time_1.h"
|
||||
|
||||
extern void system_clock_4 (GFC_INTEGER_4 *, GFC_INTEGER_4 *, GFC_INTEGER_4 *);
|
||||
export_proto(system_clock_4);
|
||||
@ -52,21 +45,21 @@ void
|
||||
system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate,
|
||||
GFC_INTEGER_4 *count_max)
|
||||
{
|
||||
#undef TCK
|
||||
#define TCK 1000
|
||||
GFC_INTEGER_4 cnt;
|
||||
GFC_INTEGER_4 mx;
|
||||
|
||||
#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
|
||||
#undef TCK
|
||||
#define TCK 1000
|
||||
struct timeval tp1;
|
||||
time_t secs;
|
||||
long nanosecs;
|
||||
|
||||
if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "tv_sec too small");
|
||||
if (sizeof (secs) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "secs too small");
|
||||
|
||||
if (gettimeofday(&tp1, NULL) == 0)
|
||||
if (gf_gettime (GF_CLOCK_MONOTONIC, &secs, &nanosecs) == 0)
|
||||
{
|
||||
GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) tp1.tv_sec * TCK;
|
||||
ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK);
|
||||
GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) secs * TCK;
|
||||
ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK);
|
||||
if (ucnt > GFC_INTEGER_4_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_4_HUGE - 1;
|
||||
else
|
||||
@ -83,22 +76,7 @@ system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate,
|
||||
*count_max = 0;
|
||||
return;
|
||||
}
|
||||
#elif defined(HAVE_TIME_H)
|
||||
GFC_UINTEGER_4 ucnt;
|
||||
|
||||
if (sizeof (time_t) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "time_t too small");
|
||||
|
||||
ucnt = time (NULL);
|
||||
if (ucnt > GFC_INTEGER_4_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_4_HUGE - 1;
|
||||
else
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_4_HUGE;
|
||||
#else
|
||||
cnt = - GFC_INTEGER_4_HUGE;
|
||||
mx = 0;
|
||||
#endif
|
||||
if (count != NULL)
|
||||
*count = cnt;
|
||||
if (count_rate != NULL)
|
||||
@ -114,39 +92,26 @@ void
|
||||
system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate,
|
||||
GFC_INTEGER_8 *count_max)
|
||||
{
|
||||
#undef TCK
|
||||
#define TCK 1000000000
|
||||
GFC_INTEGER_8 cnt;
|
||||
GFC_INTEGER_8 mx;
|
||||
|
||||
#if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY)
|
||||
#undef TCK
|
||||
#define TCK 1000000
|
||||
struct timeval tp1;
|
||||
time_t secs;
|
||||
long nanosecs;
|
||||
|
||||
if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "tv_sec too small");
|
||||
if (sizeof (secs) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "secs too small");
|
||||
|
||||
if (gettimeofday(&tp1, NULL) == 0)
|
||||
if (gf_gettime (GF_CLOCK_MONOTONIC, &secs, &nanosecs) == 0)
|
||||
{
|
||||
if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_8))
|
||||
{
|
||||
GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) tp1.tv_sec * TCK;
|
||||
ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK);
|
||||
if (ucnt > GFC_INTEGER_4_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_4_HUGE - 1;
|
||||
else
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_4_HUGE;
|
||||
}
|
||||
GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) secs * TCK;
|
||||
ucnt += (nanosecs + 500000000 / TCK) / (1000000000 / TCK);
|
||||
if (ucnt > GFC_INTEGER_8_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_8_HUGE - 1;
|
||||
else
|
||||
{
|
||||
GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) tp1.tv_sec * TCK;
|
||||
ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK);
|
||||
if (ucnt > GFC_INTEGER_8_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_8_HUGE - 1;
|
||||
else
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_8_HUGE;
|
||||
}
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_8_HUGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -159,31 +124,7 @@ system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate,
|
||||
|
||||
return;
|
||||
}
|
||||
#elif defined(HAVE_TIME_H)
|
||||
if (sizeof (time_t) < sizeof (GFC_INTEGER_4))
|
||||
internal_error (NULL, "time_t too small");
|
||||
else if (sizeof (time_t) == sizeof (GFC_INTEGER_4))
|
||||
{
|
||||
GFC_UINTEGER_4 ucnt = time (NULL);
|
||||
if (ucnt > GFC_INTEGER_4_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_4_HUGE - 1;
|
||||
else
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_4_HUGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GFC_UINTEGER_8 ucnt = time (NULL);
|
||||
if (ucnt > GFC_INTEGER_8_HUGE)
|
||||
cnt = ucnt - GFC_INTEGER_8_HUGE - 1;
|
||||
else
|
||||
cnt = ucnt;
|
||||
mx = GFC_INTEGER_8_HUGE;
|
||||
}
|
||||
#else
|
||||
cnt = - GFC_INTEGER_8_HUGE;
|
||||
mx = 0;
|
||||
#endif
|
||||
|
||||
if (count != NULL)
|
||||
*count = cnt;
|
||||
if (count_rate != NULL)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Implementation of the CPU_TIME intrinsic.
|
||||
Copyright (C) 2003, 2007, 2009 Free Software Foundation, Inc.
|
||||
/* Wrappers for platform timing functions.
|
||||
Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Fortran 95 runtime library (libgfortran).
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
|
||||
Libgfortran is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
@ -60,16 +60,38 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
# include <sys/resource.h>
|
||||
#endif /* HAVE_GETRUSAGE && HAVE_SYS_RESOURCE_H */
|
||||
|
||||
/* The most accurate way to get the CPU time is getrusage ().
|
||||
If we have times(), that's good enough, too. */
|
||||
#if !defined (HAVE_GETRUSAGE) || !defined (HAVE_SYS_RESOURCE_H)
|
||||
/* For times(), we _must_ know the number of clock ticks per second. */
|
||||
# if defined (HAVE_TIMES) && (defined (HZ) || defined (_SC_CLK_TCK) || defined (CLK_TCK))
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
# if defined (HAVE_SYS_TIMES_H)
|
||||
# include <sys/times.h>
|
||||
# endif
|
||||
# ifndef HZ
|
||||
# if defined _SC_CLK_TCK
|
||||
# define HZ sysconf(_SC_CLK_TCK)
|
||||
# else
|
||||
# define HZ CLK_TCK
|
||||
# endif
|
||||
# endif
|
||||
# endif /* HAVE_TIMES etc. */
|
||||
#endif /* !HAVE_GETRUSAGE || !HAVE_SYS_RESOURCE_H */
|
||||
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ >= 3)
|
||||
# define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
|
||||
#else
|
||||
# define ATTRIBUTE_ALWAYS_INLINE
|
||||
#endif
|
||||
|
||||
static inline int __time_1 (long *, long *, long *, long *) ATTRIBUTE_ALWAYS_INLINE;
|
||||
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 a CPU time in microseconds or -1 if no
|
||||
CPU_TIME intrinsics. Returns 0 for success or -1 if no
|
||||
CPU time could be computed. */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
@ -78,7 +100,7 @@ static inline int __time_1 (long *, long *, long *, long *) ATTRIBUTE_ALWAYS_INL
|
||||
#include <windows.h>
|
||||
|
||||
static int
|
||||
__time_1 (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
{
|
||||
union {
|
||||
FILETIME ft;
|
||||
@ -112,23 +134,37 @@ __time_1 (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
#else
|
||||
|
||||
static inline int
|
||||
__time_1 (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
{
|
||||
#if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
|
||||
struct rusage usage;
|
||||
getrusage (RUSAGE_SELF, &usage);
|
||||
int err;
|
||||
err = getrusage (RUSAGE_SELF, &usage);
|
||||
|
||||
*user_sec = usage.ru_utime.tv_sec;
|
||||
*user_usec = usage.ru_utime.tv_usec;
|
||||
*system_sec = usage.ru_stime.tv_sec;
|
||||
*system_usec = usage.ru_stime.tv_usec;
|
||||
return err;
|
||||
|
||||
#elif defined HAVE_TIMES
|
||||
struct tms buf;
|
||||
clock_t err;
|
||||
err = times (&buf);
|
||||
*user_sec = buf.tms_utime / HZ;
|
||||
*user_usec = buf.tms_utime % HZ * (1000000 / HZ);
|
||||
*system_sec = buf.tms_stime / HZ;
|
||||
*system_usec = buf.tms_stime % HZ * (1000000 / HZ);
|
||||
if ((err == (clock_t) -1) && errno != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
#else /* ! HAVE_GETRUSAGE || ! HAVE_SYS_RESOURCE_H */
|
||||
#else
|
||||
|
||||
/* We have nothing to go on. Return -1. */
|
||||
*user_sec = *system_sec = 0;
|
||||
*user_usec = *system_usec = 0;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
||||
#endif
|
||||
@ -137,4 +173,71 @@ __time_1 (long *user_sec, long *user_usec, long *system_sec, long *system_usec)
|
||||
#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
|
||||
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
#define GF_CLOCK_MONOTONIC CLOCK_MONOTONIC
|
||||
#else
|
||||
#define GF_CLOCK_REALTIME GF_CLOCK_REALTIME
|
||||
#endif
|
||||
|
||||
/* Arguments:
|
||||
clock_id - INPUT, must be either GF_CLOCK_REALTIME or GF_CLOCK_MONOTONIC
|
||||
secs - OUTPUT, seconds
|
||||
nanosecs - OUTPUT, OPTIONAL, nanoseconds
|
||||
|
||||
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.
|
||||
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec ts;
|
||||
int err;
|
||||
err = clock_gettime (clock_id, &ts);
|
||||
*secs = ts.tv_sec;
|
||||
if (nanosecs)
|
||||
*nanosecs = ts.tv_nsec;
|
||||
return err;
|
||||
#elif HAVE_GETTIMEOFDAY
|
||||
struct timeval tv;
|
||||
int err;
|
||||
err = gettimeofday (&tv, NULL);
|
||||
*secs = tv.tv_sec;
|
||||
if (nanosecs)
|
||||
*nanosecs = tv.tv_usec * 1000;
|
||||
return err;
|
||||
#elif HAVE_TIME
|
||||
time_t t, t2;
|
||||
t = time (&t2);
|
||||
*secs = t2;
|
||||
if (nanosecs)
|
||||
*nanosecs = 0;
|
||||
if (t == ((time_t)-1))
|
||||
return -1;
|
||||
return 0;
|
||||
#else
|
||||
*secs = 0;
|
||||
if (nanosecs)
|
||||
*nanosecs = 0;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* LIBGFORTRAN_TIME_H */
|
||||
|
Loading…
Reference in New Issue
Block a user