00001 /** @file rutz/time.h user-friendly wrapper around timeval */ 00002 00003 /////////////////////////////////////////////////////////////////////// 00004 // 00005 // Copyright (c) 2002-2004 California Institute of Technology 00006 // Copyright (c) 2004-2007 University of Southern California 00007 // Rob Peters <rjpeters at usc dot edu> 00008 // 00009 // created: Thu Nov 7 16:43:03 2002 00010 // commit: $Id: time.h 8667 2007-08-07 18:57:58Z rjpeters $ 00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/time.h $ 00012 // 00013 // -------------------------------------------------------------------- 00014 // 00015 // This file is part of GroovX. 00016 // [http://ilab.usc.edu/rjpeters/groovx/] 00017 // 00018 // GroovX is free software; you can redistribute it and/or modify it 00019 // under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation; either version 2 of the License, or 00021 // (at your option) any later version. 00022 // 00023 // GroovX is distributed in the hope that it will be useful, but 00024 // WITHOUT ANY WARRANTY; without even the implied warranty of 00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00026 // General Public License for more details. 00027 // 00028 // You should have received a copy of the GNU General Public License 00029 // along with GroovX; if not, write to the Free Software Foundation, 00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00031 // 00032 /////////////////////////////////////////////////////////////////////// 00033 00034 #ifndef GROOVX_RUTZ_TIME_H_UTC20050626084020_DEFINED 00035 #define GROOVX_RUTZ_TIME_H_UTC20050626084020_DEFINED 00036 00037 #include <sys/time.h> 00038 // struct timeval { 00039 // unsigned long tv_sec; /* seconds since Jan. 1, 1970 */ 00040 // long tv_usec; /* and microseconds */ 00041 // }; 00042 00043 namespace rutz 00044 { 00045 class time; 00046 } 00047 00048 /// A simple wrapper around timeval. 00049 /** All operations provide the no-throw guarantee. */ 00050 class rutz::time 00051 { 00052 public: 00053 /// Construct with time=0. 00054 time() throw() : m_timeval() 00055 { 00056 reset(); 00057 } 00058 00059 /// Construct from a timeval. 00060 time(const timeval& t) throw() : m_timeval(t) 00061 { 00062 normalize(this->m_timeval); 00063 } 00064 00065 /// Construct with given seconds+microseconds values. 00066 time(unsigned long s, long us) throw() : m_timeval() 00067 { 00068 reset(s, us); 00069 } 00070 00071 explicit time(double ss) throw() : m_timeval() 00072 { 00073 const unsigned long s = (unsigned long)(ss); 00074 const long us = long((ss - s) * 1000000); 00075 reset(s, us); 00076 } 00077 00078 /// Copy construct. 00079 time(const time& x) throw() : m_timeval(x.m_timeval) {} 00080 00081 /// Destruct. 00082 ~time() throw() {} 00083 00084 /// Create a time representing current wall-clock time. 00085 static time wall_clock_now() throw(); 00086 00087 /// Create a time representing the current process's user cpu usage. 00088 static time user_rusage() throw(); 00089 00090 /// Create a time representing the current process's sys cpu usage. 00091 static time sys_rusage() throw(); 00092 00093 /// Create a time representing the current process's total user+sys cpu usage. 00094 static time rusage_now() throw() 00095 { return rutz::time::user_rusage() + rutz::time::sys_rusage(); } 00096 00097 /// Reset to given seconds+microseconds values. 00098 void reset(unsigned long s = 0, long us = 0) throw() 00099 { 00100 m_timeval.tv_sec = s; 00101 m_timeval.tv_usec = us; 00102 normalize(this->m_timeval); 00103 } 00104 00105 /// Assignment operator. 00106 time& operator=(const time& x) throw() 00107 { 00108 m_timeval = x.m_timeval; 00109 return *this; 00110 } 00111 00112 /// Addition operator. 00113 time operator+(const time& t2) const throw() 00114 { 00115 timeval result; 00116 result.tv_sec = this->m_timeval.tv_sec + t2.m_timeval.tv_sec; 00117 result.tv_usec = this->m_timeval.tv_usec + t2.m_timeval.tv_usec; 00118 00119 normalize(result); 00120 00121 return time(result); 00122 } 00123 00124 /// In-place addition operator. 00125 time& operator+=(const time& t2) throw() 00126 { 00127 m_timeval.tv_sec += t2.m_timeval.tv_sec; 00128 m_timeval.tv_usec += t2.m_timeval.tv_usec; 00129 00130 normalize(this->m_timeval); 00131 00132 return *this; 00133 } 00134 00135 /// Subtraction operator. 00136 time operator-(const time& t2) const throw() 00137 { 00138 timeval result; 00139 result.tv_sec = this->m_timeval.tv_sec - t2.m_timeval.tv_sec; 00140 result.tv_usec = this->m_timeval.tv_usec - t2.m_timeval.tv_usec; 00141 00142 normalize(result); 00143 00144 return time(result); 00145 } 00146 00147 /// In-place subtraction operator. 00148 time& operator-=(const time& t2) throw() 00149 { 00150 m_timeval.tv_sec -= t2.m_timeval.tv_sec; 00151 m_timeval.tv_usec -= t2.m_timeval.tv_usec; 00152 00153 normalize(this->m_timeval); 00154 00155 return *this; 00156 } 00157 00158 /// Less-than comparison 00159 bool operator<(const time& t2) const throw() 00160 { 00161 return (m_timeval.tv_sec < t2.m_timeval.tv_sec) 00162 || 00163 (m_timeval.tv_sec == t2.m_timeval.tv_sec 00164 && m_timeval.tv_usec < t2.m_timeval.tv_usec); 00165 } 00166 00167 /// Less-than-or-equal comparison 00168 bool operator<=(const time& t2) const throw() 00169 { 00170 return (m_timeval.tv_sec <= t2.m_timeval.tv_sec) 00171 || 00172 (m_timeval.tv_sec == t2.m_timeval.tv_sec 00173 && m_timeval.tv_usec <= t2.m_timeval.tv_usec); 00174 } 00175 00176 /// Equality comparison 00177 bool operator==(const time& t2) const throw() 00178 { 00179 return (m_timeval.tv_sec == t2.m_timeval.tv_sec 00180 && m_timeval.tv_usec == t2.m_timeval.tv_usec); 00181 } 00182 00183 /// Greater-than comparison 00184 bool operator>(const time& t2) const throw() 00185 { 00186 return (m_timeval.tv_sec > t2.m_timeval.tv_sec) 00187 || 00188 (m_timeval.tv_sec == t2.m_timeval.tv_sec 00189 && m_timeval.tv_usec > t2.m_timeval.tv_usec); 00190 } 00191 00192 /// Greater-than-or-equal comparison 00193 bool operator>=(const time& t2) const throw() 00194 { 00195 return (m_timeval.tv_sec >= t2.m_timeval.tv_sec) 00196 || 00197 (m_timeval.tv_sec == t2.m_timeval.tv_sec 00198 && m_timeval.tv_usec >= t2.m_timeval.tv_usec); 00199 } 00200 00201 /// Return time in floating-point seconds. 00202 double sec() const throw() 00203 { 00204 return double(m_timeval.tv_sec) + m_timeval.tv_usec / 1000000.0; 00205 } 00206 00207 /// Return time in floating-point milliseconds. 00208 double msec() const throw() 00209 { 00210 return (m_timeval.tv_sec * 1000.0) + (m_timeval.tv_usec / 1000.0); 00211 } 00212 00213 /// Return time in floating-point microseconds. 00214 double usec() const throw() 00215 { 00216 return (m_timeval.tv_sec * 1000000.0) + double(m_timeval.tv_usec); 00217 } 00218 00219 /// Return internal timeval. 00220 const timeval& tval() const throw() 00221 { 00222 return m_timeval; 00223 } 00224 00225 /// Conversion operator to timeval. 00226 operator const timeval&() const throw() 00227 { 00228 return m_timeval; 00229 } 00230 00231 private: 00232 /// Avoid overflow/underflow in the timeval's microseconds field. 00233 static void normalize(timeval& t) throw() 00234 { 00235 long s = t.tv_usec / 1000000; 00236 00237 if (s != 0) 00238 { 00239 t.tv_sec += s; 00240 t.tv_usec -= (s * 1000000); 00241 } 00242 } 00243 00244 timeval m_timeval; 00245 }; 00246 00247 static const char __attribute__((used)) vcid_groovx_rutz_time_h_utc20050626084020[] = "$Id: time.h 8667 2007-08-07 18:57:58Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/time.h $"; 00248 #endif // !GROOVX_RUTZ_TIME_H_UTC20050626084020_DEFINED