#include "config.h"
#include <sys/types.h>
#include "libgfortran.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#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
#endif
#if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
# include <sys/resource.h>
#else
# if defined (HAVE_TIMES) && (defined (HZ) || defined (_SC_CLK_TCK) || defined (CLK_TCK))
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
# endif
# include <sys/times.h>
# ifndef HZ
# if defined _SC_CLK_TCK
# define HZ sysconf(_SC_CLK_TCK)
# else
# define HZ CLK_TCK
# endif
# endif
# endif
#endif
#if defined (__GNUC__) && (__GNUC__ >= 3)
# define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
#else
# define ATTRIBUTE_ALWAYS_INLINE
#endif
static inline void __cpu_time_1 (long *, long *) ATTRIBUTE_ALWAYS_INLINE;
#ifdef __MINGW32__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void
__cpu_time_1 (long *sec, long *usec)
{
union {
FILETIME ft;
unsigned long long ulltime;
} kernel_time, user_time;
FILETIME unused1, unused2;
unsigned long long total_time;
if (GetVersion () >= 0x80000000)
{
*sec = -1;
*usec = 0;
return;
}
GetProcessTimes (GetCurrentProcess (), &unused1, &unused2,
&kernel_time.ft, &user_time.ft);
total_time = (kernel_time.ulltime + user_time.ulltime)/10;
*sec = total_time / 1000000;
*usec = total_time % 1000000;
}
#else
static inline void
__cpu_time_1 (long *sec, long *usec)
{
#if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
struct rusage usage;
getrusage (0, &usage);
*sec = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
*usec = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
#else
#ifdef HAVE_TIMES
struct tms buf;
times (&buf);
*sec = 0;
*usec = (buf.tms_utime + buf.tms_stime) * (1000000 / HZ);
#else
*sec = -1;
*usec = 0;
#endif
#endif
}
#endif
extern void cpu_time_4 (GFC_REAL_4 *);
iexport_proto(cpu_time_4);
void cpu_time_4 (GFC_REAL_4 *time)
{
long sec, usec;
__cpu_time_1 (&sec, &usec);
*time = sec + usec * (GFC_REAL_4)1.e-6;
}
iexport(cpu_time_4);
extern void cpu_time_8 (GFC_REAL_8 *);
export_proto(cpu_time_8);
void cpu_time_8 (GFC_REAL_8 *time)
{
long sec, usec;
__cpu_time_1 (&sec, &usec);
*time = sec + usec * (GFC_REAL_8)1.e-6;
}
#ifdef HAVE_GFC_REAL_10
extern void cpu_time_10 (GFC_REAL_10 *);
export_proto(cpu_time_10);
void cpu_time_10 (GFC_REAL_10 *time)
{
long sec, usec;
__cpu_time_1 (&sec, &usec);
*time = sec + usec * (GFC_REAL_10)1.e-6;
}
#endif
#ifdef HAVE_GFC_REAL_16
extern void cpu_time_16 (GFC_REAL_16 *);
export_proto(cpu_time_16);
void cpu_time_16 (GFC_REAL_16 *time)
{
long sec, usec;
__cpu_time_1 (&sec, &usec);
*time = sec + usec * (GFC_REAL_16)1.e-6;
}
#endif
extern void second_sub (GFC_REAL_4 *);
export_proto(second_sub);
void
second_sub (GFC_REAL_4 *s)
{
cpu_time_4 (s);
}
extern GFC_REAL_4 second (void);
export_proto(second);
GFC_REAL_4
second (void)
{
GFC_REAL_4 s;
cpu_time_4 (&s);
return s;
}