time.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 The FLWOR Foundation.
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #pragma once
00017 #ifndef ZORBA_UTIL_TIME_H
00018 #define ZORBA_UTIL_TIME_H
00019 
00020 /**
00021  * This header includes utility functions for certain timing-related
00022  * operations, namely getting current wall-clock time and current
00023  * CPU-used time values in a platform-dependent fashion, and computing
00024  * deltas for both types.
00025  *
00026  * Types:
00027  *   cputime - type representing CPU time utilized thus far by this process
00028  *   walltime - type representing wall-clock time since some
00029  *     platform-dependent epoch
00030  *
00031  * Function signatures:
00032  *   void get_current_cputime(cputime& t) - returns current CPU time
00033  *
00034  *   double get_cputime_elapsed(const cputime& t0, const cputime& t1) -
00035  *     calculates elapsed CPU time (in ms) between two cputimes
00036  *
00037  *   void get_current_walltime(walltime& t) - returns current wall-clock time
00038  *
00039  *   double get_walltime_elapsed(const walltime& t0, const walltime& t1) -
00040  *    calculates elapsed wall-clock time (in ms) between two walltimes
00041  */
00042 
00043 /**
00044  * TODO These functions should probably be defined in a .cpp file
00045  * somewhere rather than here in time.h; as it is they will be
00046  * compiled into every .o that uses them. So far, though, this is only
00047  * zorbacmd and the implementation of fn:doc(), so it's not too bad.
00048  */
00049 
00050 namespace zorba 
00051 {
00052 
00053   namespace time
00054   {
00055 
00056     //
00057     //
00058     // Types and functions for CPU time
00059     //
00060     //
00061 
00062 #if (defined(ZORBA_HAVE_CLOCKGETTIME_FUNCTION) & defined(_POSIX_CPUTIME))
00063 
00064 #include <time.h>
00065 
00066     typedef struct timespec cputime;
00067 
00068     inline double get_cputime_elapsed (const cputime& t0, const cputime& t1)
00069     {
00070       return ((t1.tv_sec - t0.tv_sec) * 1000.0) +
00071         ((t1.tv_nsec - t0.tv_nsec) / 1000000.0);
00072     }
00073 
00074     inline void get_current_cputime (cputime& t)
00075     {
00076       clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
00077     }
00078 
00079 #elif defined(ZORBA_HAVE_RUSAGE_FUNCTION)
00080 
00081 #include <sys/time.h>
00082 #include <sys/resource.h>
00083 
00084     typedef struct timeval cputime;
00085 
00086     inline double get_cputime_elapsed (const cputime& t0, const cputime& t1) 
00087     {
00088       return ((t1.tv_sec - t0.tv_sec) * 1000.0) +
00089         ((t1.tv_usec - t0.tv_usec) / 1000.0);
00090     }
00091 
00092     inline void get_current_cputime (cputime& t) 
00093     {
00094       struct rusage ru;
00095       getrusage (RUSAGE_SELF, &ru);
00096       t = ru.ru_utime;
00097     }
00098 
00099 #else /* no rusage, no clock_gettime */
00100 
00101 #include <time.h>
00102 
00103     typedef clock_t cputime;
00104 
00105     inline double get_cputime_elapsed (const cputime& t0, const cputime& t1) 
00106     {
00107       return (double) (t1 - t0) / (CLOCKS_PER_SEC / 1000);
00108     }
00109 
00110     inline void get_current_cputime (cputime& t)
00111     {
00112       t = clock ();
00113     }
00114 
00115 #endif /* ZORBA_HAVE_CLOCKGETTIME_FUNCTION */
00116 
00117 
00118     //
00119     //
00120     // Types and functions for wall-clock time
00121     //
00122     //
00123 
00124 #if defined(ZORBA_HAVE_CLOCKGETTIME_FUNCTION)
00125 
00126 #include <time.h>
00127 
00128     typedef struct timespec walltime;
00129 
00130     inline double get_walltime_elapsed (const walltime& t0, const walltime& t1)
00131     {
00132       return ((t1.tv_sec - t0.tv_sec) * 1000.0) +
00133         ((t1.tv_nsec - t0.tv_nsec) / 1000000.0);
00134     }
00135 
00136     inline void get_current_walltime (walltime& t)
00137     {
00138 #ifdef _POSIX_MONOTONIC_CLOCK
00139       clock_gettime(CLOCK_MONOTONIC, &t);
00140 #else
00141       clock_gettime(CLOCK_REALTIME, &t);
00142 #endif
00143     }
00144 
00145     inline long get_walltime_in_millis(const walltime& t)
00146     {
00147       return t.tv_sec * 1000 + t.tv_nsec / 1000000;
00148     }
00149 
00150 #elif defined(WIN32)
00151 
00152     // TODO: Should maybe use QueryPerformanceCounter() or
00153     // GetSystemTimeAsFileTime() for this, rather than ftime(), but I
00154     // don't know enough about any of these alternatives to choose
00155     // one. See http://msdn.microsoft.com/en-us/magazine/cc163996.aspx .
00156 
00157 #include <sys/timeb.h>
00158 
00159 #ifdef WINCE
00160     typedef struct timeb walltime;
00161 #else
00162     typedef struct _timeb walltime;
00163 #endif
00164 
00165     inline double get_walltime_elapsed (const walltime& t0, const walltime& t1) 
00166     {
00167       return ((t1.time - t0.time) * 1000.0) + (t1.millitm - t0.millitm);
00168     }
00169 
00170     inline void get_current_walltime (walltime& t) 
00171     {
00172 #ifdef WINCE
00173       ftime(&t);
00174 #else
00175       _ftime_s(&t);
00176 #endif
00177     }
00178   
00179     inline long get_walltime_in_millis(const walltime& t)
00180     {
00181       return t.time * 1000 + t.millitm;
00182     }
00183 
00184 #else /* not Windows, and no clock_gettime() */
00185 
00186 #include <time.h>
00187 #include <sys/time.h>
00188 
00189     typedef struct timeval walltime;
00190 
00191     inline double get_walltime_elapsed (const walltime& t0, const walltime& t1) 
00192     {
00193       return ((t1.tv_sec - t0.tv_sec) * 1000.0) +
00194         ((t1.tv_usec - t0.tv_usec) / 1000.0);
00195     }
00196 
00197     inline void get_current_walltime (walltime& t)
00198     {
00199       gettimeofday(&t, NULL);
00200     }
00201   
00202     inline long get_walltime_in_millis(const walltime& t)
00203     {
00204       return t.tv_sec * 1000 + t.tv_usec / 1000;
00205     }
00206 
00207 #endif /* ZORBA_HAVE_CLOCKGETTIME_FUNCTION */
00208 
00209   }  // ::time
00210 
00211 }  // ::zorba
00212 
00213 #endif
00214 
00215 /*
00216  * Local variables:
00217  * mode: c++
00218  * End:
00219  */
00220 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus