diff options
-rw-r--r-- | configure.ac | 21 | ||||
-rw-r--r-- | libdimension/platform.c | 50 |
2 files changed, 58 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac index 06e9b0a..d763041 100644 --- a/configure.ac +++ b/configure.ac @@ -145,6 +145,27 @@ AC_COMPILE_IFELSE([ AC_MSG_RESULT([no])] ) +AC_MSG_CHECKING([for getrusage()]) +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [ + #include <stddef.h> + #include <sys/time.h> + #include <sys/resource.h> + ], + [ + struct timeval real; + gettimeofday(&real, NULL); + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + ] + )], + [AC_DEFINE([DMNSN_GETRUSAGE], [1]) + AC_MSG_RESULT([yes])], + [AC_DEFINE([DMNSN_GETRUSAGE], [0]) + AC_MSG_RESULT([no])] +) + AC_MSG_CHECKING([for times()]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM( diff --git a/libdimension/platform.c b/libdimension/platform.c index a54a3de..a27343d 100644 --- a/libdimension/platform.c +++ b/libdimension/platform.c @@ -42,6 +42,10 @@ #if DMNSN_TIMES #include <sys/times.h> #endif +#if DMNSN_GETRUSAGE + #include <sys/time.h> + #include <sys/resource.h> +#endif void dmnsn_backtrace(FILE *file) @@ -107,15 +111,34 @@ dmnsn_ncpus(void) #endif } -#if DMNSN_TIMES -/** Clock ticks per second. */ -static long clk_tck = 0; +#if DMNSN_GETRUSAGE +/** Convert a struct timeval to a double. */ +static inline double +dmnsn_timeval2double(struct timeval tv) +{ + return tv.tv_sec + tv.tv_usec/1.0e6; +} #endif void dmnsn_get_times(dmnsn_timer *timer) { -#if DMNSN_TIMES +#if DMNSN_GETRUSAGE + struct timeval real; + gettimeofday(&real, NULL); + + struct rusage usage; + if (getrusage(RUSAGE_SELF, &usage) == 0) { + timer->real = dmnsn_timeval2double(real); + timer->user = dmnsn_timeval2double(usage.ru_utime); + timer->system = dmnsn_timeval2double(usage.ru_stime); + } else { + dmnsn_warning("getrusage() failed."); + timer->real = timer->user = timer->system = 0.0; + } +#elif DMNSN_TIMES + static long clk_tck = 0; + /* Figure out the clock ticks per second */ if (!clk_tck) { clk_tck = sysconf(_SC_CLK_TCK); @@ -127,9 +150,14 @@ dmnsn_get_times(dmnsn_timer *timer) struct tms buf; clock_t real = times(&buf); - timer->real = (double)real/clk_tck; - timer->user = (double)buf.tms_utime/clk_tck; - timer->system = (double)buf.tms_stime/clk_tck; + if (real == (clock_t)-1) { + dmnsn_warning("times() failed."); + timer->real = timer->user = timer->system = 0.0; + } else { + timer->real = (double)real/clk_tck; + timer->user = (double)buf.tms_utime/clk_tck; + timer->system = (double)buf.tms_stime/clk_tck; + } #elif defined(_WIN32) FILETIME real; GetSystemTimeAsFileTime(&real); @@ -147,13 +175,9 @@ dmnsn_get_times(dmnsn_timer *timer) = (((uint64_t)system.dwHighDateTime << 32) + system.dwLowDateTime)/1.0e7; } else { dmnsn_warning("GetProcessTimes() failed."); - timer->real = 0.0; - timer->user = 0.0; - timer->system = 0.0; + timer->real = timer->user = timer->system = 0.0; } #else - timer->real = 0.0; - timer->user = 0.0; - timer->system = 0.0; + timer->real = timer->user = timer->system = 0.0; #endif } |