/* timing.c - Timing routines for computing elapsed wall time Copyright (C) 1994 Michael D. Black Copyright (C) 1996, 1997 Uwe Ohse This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. originally written by Michael D. Black, mblack@csihq.com */ #include "zglobal.h" #include "timing.h" #if HAVE_SYS_PARAM_H #include #endif #if !defined(TIME_WITH_SYS_TIME) && !defined(HAVE_SYS_TIME_H) /* can't use gettimeofday without struct timeval */ # undef HAVE_GETTIMEOFDAY #endif /* Prefer gettimeofday to ftime to times. */ #if defined(HAVE_GETTIMEOFDAY) # undef HAVE_FTIME # undef HAVE_TIMES #else # if defined(HAVE_FTIME) # undef HAVE_TIMES # endif #endif #ifdef HAVE_FTIME # include #endif #ifdef HAVE_TIMES # if HAVE_SYS_TIMES_H # include # endif # ifdef _SC_CLK_TCK # define HAVE_SC_CLK_TCK 1 # else # define HAVE_SC_CLK_TCK 0 # endif /* TIMES_TICK may have been set in policy.h, or we may be able to get it using sysconf. If neither is the case, try to find a useful definition from the system header files. */ # if !defined(TIMES_TICK) && (!defined(HAVE_SYSCONF) || !defined(HAVE_SC_CLK_TCK)) # ifdef CLK_TCK # define TIMES_TICK CLK_TCK # else /* ! defined (CLK_TCK) */ # ifdef HZ # define TIMES_TICK HZ # endif /* defined (HZ) */ # endif /* ! defined (CLK_TCK) */ #else # endif /* TIMES_TICK == 0 && (! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK) */ # ifndef TIMES_TICK # define TIMES_TICK 0 # endif #endif /* HAVE_TIMES */ #ifdef HAVE_GETTIMEOFDAY /* collides with Solaris 2.5 prototype? */ /* int gettimeofday (struct timeval *tv, struct timezone *tz); */ #endif double timing (int reset, time_t *nowp) { static double elaptime, starttime, stoptime; double yet; #define NEED_TIME #ifdef HAVE_GETTIMEOFDAY struct timeval tv; struct timezone tz; #ifdef DST_NONE tz.tz_dsttime = DST_NONE; #else tz.tz_dsttime = 0; #endif gettimeofday (&tv, &tz); yet=tv.tv_sec + tv.tv_usec/1000000.0; #undef NEED_TIME #endif #ifdef HAVE_FTIME static int fbad=0; if (! fbad) { struct timeb stime; static struct timeb slast; (void) ftime (&stime); /* On some systems, such as SCO 3.2.2, ftime can go backwards in time. If we detect this, we switch to using time. */ if (slast.time != 0 && (stime.time < slast.time || (stime.time == slast.time && stime.millitm < slast.millitm))) fbad = 1; else { yet = stime.millitm / 1000.0 + stime.time; slast = stime; } } if (fbad) yet=(double) time(NULL); #undef NEED_TIME #endif #ifdef HAVE_TIMES struct tms s; long i; static int itick; if (itick == 0) { #if TIMES_TICK == 0 #if HAVE_SYSCONF && HAVE_SC_CLK_TCK itick = (int) sysconf (_SC_CLK_TCK); #else /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */ const char *z; z = getenv ("HZ"); if (z != NULL) itick = (int) strtol (z, (char **) NULL, 10); /* If we really couldn't get anything, just use 60. */ if (itick == 0) itick = 60; #endif /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */ #else /* TIMES_TICK != 0 */ itick = TIMES_TICK; #endif /* TIMES_TICK == 0 */ } yet = ((double) times (&s)) / itick; #undef NEED_TIME #endif #ifdef NEED_TIME yet=(double) time(NULL); #endif if (nowp) *nowp=(time_t) yet; if (reset) { starttime = yet; return starttime; } else { stoptime = yet; elaptime = stoptime - starttime; return elaptime; } } /*#define TEST*/ #ifdef TEST main() { int i; printf("timing %g\n",timing(1)); printf("timing %g\n",timing(0)); for(i=0;i<20;i++){ sleep(1); printf("timing %g\n",timing(0)); } } #endif