#include "options.h"
#include "json.h"
-#ifndef HAVE_CLOCK_T
-typedef int clock_t;
-#endif
-
-#ifndef HAVE_STRUCT_TMS
-struct tms
-{
- clock_t tms_utime;
- clock_t tms_stime;
- clock_t tms_cutime;
- clock_t tms_cstime;
-};
-#endif
-
-#ifndef RUSAGE_SELF
-# define RUSAGE_SELF 0
-#endif
-
-/* Calculation of scale factor to convert ticks to seconds.
- We mustn't use CLOCKS_PER_SEC except with clock(). */
-#if HAVE_SYSCONF && defined _SC_CLK_TCK
-# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
-#else
-# ifdef CLK_TCK
-# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
-# else
-# ifdef HZ
-# define TICKS_PER_SECOND HZ /* traditional UNIX */
-# else
-# define TICKS_PER_SECOND 100 /* often the correct value */
-# endif
-# endif
-#endif
-
-/* Prefer times to getrusage to clock (each gives successively less
- information). */
-#ifdef HAVE_TIMES
-# if defined HAVE_DECL_TIMES && !HAVE_DECL_TIMES
- extern clock_t times (struct tms *);
-# endif
-# define USE_TIMES
-# define HAVE_USER_TIME
-# define HAVE_SYS_TIME
-# define HAVE_WALL_TIME
-#else
-#ifdef HAVE_GETRUSAGE
-# if defined HAVE_DECL_GETRUSAGE && !HAVE_DECL_GETRUSAGE
- extern int getrusage (int, struct rusage *);
-# endif
-# define USE_GETRUSAGE
-# define HAVE_USER_TIME
-# define HAVE_SYS_TIME
-#else
-#ifdef HAVE_CLOCK
-# if defined HAVE_DECL_CLOCK && !HAVE_DECL_CLOCK
- extern clock_t clock (void);
-# endif
-# define USE_CLOCK
-# define HAVE_USER_TIME
-#endif
-#endif
-#endif
-
-/* libc is very likely to have snuck a call to sysconf() into one of
- the underlying constants, and that can be very slow, so we have to
- precompute them. Whose wonderful idea was it to make all those
- _constants_ variable at run time, anyway? */
-#define NANOSEC_PER_SEC 1000000000
-#ifdef USE_TIMES
-static uint64_t ticks_to_nanosec;
-#define TICKS_TO_NANOSEC (NANOSEC_PER_SEC / TICKS_PER_SECOND)
-#endif
-
-#ifdef USE_CLOCK
-static uint64_t clocks_to_nanosec;
-#define CLOCKS_TO_NANOSEC (NANOSEC_PER_SEC / CLOCKS_PER_SEC)
-#endif
-
/* Non-NULL if timevars should be used. In GCC, this happens with
the -ftime-report flag. */
timer::timevar_def *def = &m_hash_map.get_or_insert (item_name, &existed);
if (!existed)
{
- def->elapsed.user = 0;
- def->elapsed.sys = 0;
def->elapsed.wall = 0;
def->name = item_name;
def->standalone = 0;
return arr;
}
-/* Fill the current times into TIME. The definition of this function
- also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
- HAVE_WALL_TIME macros. */
+/* Fill the current times into TIME, and define HAVE_WALL_TIME if there. */
static void
get_time (struct timevar_time_def *now)
{
- now->user = 0;
- now->sys = 0;
now->wall = 0;
now->ggc_mem = timevar_ggc_mem_total;
- {
-#ifdef USE_TIMES
- struct tms tms;
- now->wall = times (&tms) * ticks_to_nanosec;
- now->user = tms.tms_utime * ticks_to_nanosec;
- now->sys = tms.tms_stime * ticks_to_nanosec;
-#endif
-#ifdef USE_GETRUSAGE
- struct rusage rusage;
- getrusage (RUSAGE_SELF, &rusage);
- now->user = rusage.ru_utime.tv_sec * NANOSEC_PER_SEC
- + rusage.ru_utime.tv_usec * 1000;
- now->sys = rusage.ru_stime.tv_sec * NANOSEC_PER_SEC
- + rusage.ru_stime.tv_usec * 1000;
+#if _POSIX_C_SOURCE >= 199309L
+ struct timespec ts;
+ clock_gettime (CLOCK_MONOTONIC, &ts);
+ now->wall = ts.tv_sec * 1000000000 + ts.tv_nsec;
+ return;
+#define HAVE_WALL_TIME 1
#endif
-#ifdef USE_CLOCK
- now->user = clock () * clocks_to_nanosec;
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ now->wall = tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
+#define HAVE_WALL_TIME 1
#endif
- }
}
/* Add the difference between STOP_TIME and START_TIME to TIMER. */
struct timevar_time_def *start_time,
struct timevar_time_def *stop_time)
{
- timer->user += stop_time->user - start_time->user;
- timer->sys += stop_time->sys - start_time->sys;
timer->wall += stop_time->wall - start_time->wall;
timer->ggc_mem += stop_time->ggc_mem - start_time->ggc_mem;
}
const timevar_time_def &start_time,
const timevar_time_def &stop_time)
{
- out->user = stop_time.user - start_time.user;
- out->sys = stop_time.sys - start_time.sys;
out->wall = stop_time.wall - start_time.wall;
out->ggc_mem = stop_time.ggc_mem - start_time.ggc_mem;
}
m_timevars[identifier__].name = name__;
#include "timevar.def"
#undef DEFTIMEVAR
-
- /* Initialize configuration-specific state.
- Ideally this would be one-time initialization. */
-#ifdef USE_TIMES
- ticks_to_nanosec = TICKS_TO_NANOSEC;
-#endif
-#ifdef USE_CLOCK
- clocks_to_nanosec = CLOCKS_TO_NANOSEC;
-#endif
}
/* Class timer's destructor. */
{
unsigned int /* timevar_id_t */ id;
const timevar_time_def *total = &m_timevars[TV_TOTAL].elapsed;
- uint64_t phase_user = 0;
- uint64_t phase_sys = 0;
uint64_t phase_wall = 0;
size_t phase_ggc_mem = 0;
static char phase_prefix[] = "phase ";
if (startswith (tv->name, phase_prefix))
{
- phase_user += tv->elapsed.user;
- phase_sys += tv->elapsed.sys;
phase_wall += tv->elapsed.wall;
phase_ggc_mem += tv->elapsed.ggc_mem;
}
}
- if (phase_user > total->user
- || phase_sys > total->sys
- || phase_wall > total->wall
- || phase_ggc_mem > total->ggc_mem)
+ if (phase_wall > total->wall || phase_ggc_mem > total->ggc_mem)
{
fprintf (fp, "Timing error: total of phase timers exceeds total time.\n");
- if (phase_user > total->user)
- fprintf (fp, "user %13" PRIu64 " > %13" PRIu64 "\n",
- phase_user, total->user);
- if (phase_sys > total->sys)
- fprintf (fp, "sys %13" PRIu64 " > %13" PRIu64 "\n",
- phase_sys, total->sys);
if (phase_wall > total->wall)
fprintf (fp, "wall %13" PRIu64 " > %13" PRIu64 "\n",
phase_wall, total->wall);
/* The timing variable name. */
fprintf (fp, " %-35s:", name);
-#ifdef HAVE_USER_TIME
- /* Print user-mode time for this process. */
- fprintf (fp, "%7.2f (%3.0f%%)",
- nanosec_to_floating_sec (elapsed.user),
- percent_of (total->user, elapsed.user));
-#endif /* HAVE_USER_TIME */
-
-#ifdef HAVE_SYS_TIME
- /* Print system-mode time for this process. */
- fprintf (fp, "%7.2f (%3.0f%%)",
- nanosec_to_floating_sec (elapsed.sys),
- percent_of (total->sys, elapsed.sys));
-#endif /* HAVE_SYS_TIME */
-
#ifdef HAVE_WALL_TIME
/* Print wall clock time elapsed. */
fprintf (fp, "%7.2f (%3.0f%%)",
{
/* 5000000 nanosec == 5e-3 seconds. */
uint64_t tiny = 5000000;
- return (elapsed.user < tiny
- && elapsed.sys < tiny
- && elapsed.wall < tiny
+ return (elapsed.wall < tiny
&& elapsed.ggc_mem < GGC_MEM_BOUND);
}
timer::print (FILE *fp)
{
/* Only print stuff if we have some sort of time information. */
-#if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
+#if defined (HAVE_WALL_TIME)
unsigned int /* timevar_id_t */ id;
const timevar_time_def *total = &m_timevars[TV_TOTAL].elapsed;
struct timevar_time_def now;
TIMEVAR. */
m_start_time = now;
- fprintf (fp, "\n%-35s%16s%14s%14s%14s\n", "Time variable", "usr", "sys",
- "wall", "GGC");
+ fprintf (fp, "\n%-35s%16s%14s\n", "Time variable", "wall", "GGC");
if (m_jit_client_items)
fputs ("GCC items:\n", fp);
for (id = 0; id < (unsigned int) TIMEVAR_LAST; ++id)
/* Print total time. */
fprintf (fp, " %-35s:", "TOTAL");
-#ifdef HAVE_USER_TIME
- fprintf (fp, "%7.2f ", nanosec_to_floating_sec (total->user));
-#endif
-#ifdef HAVE_SYS_TIME
- fprintf (fp, "%8.2f ", nanosec_to_floating_sec (total->sys));
-#endif
-#ifdef HAVE_WALL_TIME
- fprintf (fp, "%8.2f ", nanosec_to_floating_sec (total->wall));
-#endif
+ fprintf (fp, "%7.2f ", nanosec_to_floating_sec (total->wall));
fprintf (fp, PRsa (7) "\n", SIZE_AMOUNT (total->ggc_mem));
if (CHECKING_P || flag_checking)
fprintf (fp, "Configure with --enable-checking=release to enable checks.\n");
#endif
-#endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
- || defined (HAVE_WALL_TIME) */
+#endif /* defined (HAVE_WALL_TIME) */
validate_phases (fp);
}
make_json_for_timevar_time_def (const timevar_time_def &ttd)
{
json::object *obj = new json::object ();
- obj->set_float ("user", nanosec_to_floating_sec (ttd.user));
- obj->set_float ("sys", nanosec_to_floating_sec (ttd.sys));
obj->set_float ("wall", nanosec_to_floating_sec (ttd.wall));
obj->set_integer ("ggc_mem", ttd.ggc_mem);
return obj;
json::value *
timer::make_json () const
{
- /* Only generate stuff if we have some sort of time information. */
-#if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
+#if defined (HAVE_WALL_TIME)
json::object *report_obj = new json::object ();
json::array *json_arr = new json::array ();
report_obj->set ("timevars", json_arr);
return report_obj;
-#else /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
- || defined (HAVE_WALL_TIME) */
+#else /* defined (HAVE_USER_TIME) */
return NULL;
-#endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
- || defined (HAVE_WALL_TIME) */
+#endif /* !defined (HAVE_WALL_TIME) */
}
/* Get the name of the topmost item. For use by jit for validating