00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_UTILITIES_TIME_H
00021 #define ARCHON_UTILITIES_TIME_H
00022
00023 #include <sys/time.h>
00024 #include <errno.h>
00025 #include <math.h>
00026
00027 #include <ostream>
00028
00029 namespace Archon
00030 {
00031 namespace Utilities
00032 {
00033 using namespace std;
00034
00035 class Condition;
00036
00043 struct Time
00044 {
00049 Time()
00050 {
00051 ts.tv_sec = 0;
00052 ts.tv_nsec = 0;
00053 }
00054
00060 explicit Time(long seconds, long nanoSeconds = 0)
00061 {
00062 ts.tv_sec = seconds;
00063 ts.tv_nsec = nanoSeconds;
00064 }
00065
00069 explicit Time(double seconds)
00070 {
00071 double ip;
00072 ts.tv_nsec = long(modf(seconds, &ip)*1000000000L);
00073 ts.tv_sec = long(ip);
00074 }
00075
00079 static Time now()
00080 {
00081 Time t;
00082 clock_gettime(CLOCK_REALTIME, &t.ts);
00083 return t;
00084 }
00085
00090 static Time resolution()
00091 {
00092 Time t;
00093 clock_getres(CLOCK_REALTIME, &t.ts);
00094 return t;
00095 }
00096
00097 Time &operator+=(const Time &t)
00098 {
00099 ts.tv_nsec += t.ts.tv_nsec;
00100 ts.tv_sec += t.ts.tv_sec;
00101 addAdjust();
00102 return *this;
00103 }
00104
00105 Time &operator-=(const Time &t)
00106 {
00107 ts.tv_nsec -= t.ts.tv_nsec;
00108 ts.tv_sec -= t.ts.tv_sec;
00109 subAdjust();
00110 return *this;
00111 }
00112
00113 Time &operator++()
00114 {
00115 ++ts.tv_nsec;
00116 addAdjust();
00117 return *this;
00118 }
00119
00120 Time &operator--()
00121 {
00122 --ts.tv_nsec;
00123 subAdjust();
00124 return *this;
00125 }
00126
00127 Time operator++(int)
00128 {
00129 Time t = *this;
00130 ++ts.tv_nsec;
00131 addAdjust();
00132 return t;
00133 }
00134
00135 Time operator--(int)
00136 {
00137 Time t = *this;
00138 --ts.tv_nsec;
00139 subAdjust();
00140 return t;
00141 }
00142
00143 Time operator+(const Time &t) const { Time u(*this); u += t; return u; }
00144 Time operator-(const Time &t) const { Time u(*this); u -= t; return u; }
00145
00146 bool operator==(const Time &t) const
00147 {
00148 return ts.tv_sec == t.ts.tv_sec && ts.tv_nsec == t.ts.tv_nsec;
00149 }
00150
00151 bool operator!=(const Time &t) const
00152 {
00153 return ts.tv_sec != t.ts.tv_sec || ts.tv_nsec != t.ts.tv_nsec;
00154 }
00155
00156 bool operator<(const Time &t) const
00157 {
00158 return ts.tv_sec < t.ts.tv_sec ||
00159 ts.tv_sec == t.ts.tv_sec && ts.tv_nsec < t.ts.tv_nsec;
00160 }
00161
00162 bool operator>(const Time &t) const
00163 {
00164 return ts.tv_sec > t.ts.tv_sec ||
00165 ts.tv_sec == t.ts.tv_sec && ts.tv_nsec > t.ts.tv_nsec;
00166 }
00167
00168 bool operator<=(const Time &t) const
00169 {
00170 return ts.tv_sec < t.ts.tv_sec ||
00171 ts.tv_sec == t.ts.tv_sec && ts.tv_nsec <= t.ts.tv_nsec;
00172 }
00173
00174 bool operator>=(const Time &t) const
00175 {
00176 return ts.tv_sec > t.ts.tv_sec ||
00177 ts.tv_sec == t.ts.tv_sec && ts.tv_nsec >= t.ts.tv_nsec;
00178 }
00179
00184 void set(long seconds, long nanoSeconds = 0)
00185 {
00186 ts.tv_sec = seconds;
00187 ts.tv_nsec = nanoSeconds;
00188 }
00189
00194 void get(long &seconds, long &nanoSeconds) const
00195 {
00196 seconds = ts.tv_sec;
00197 nanoSeconds = ts.tv_nsec;
00198 }
00199
00200 void get(long double &seconds) const
00201 {
00202 seconds = ts.tv_nsec;
00203 seconds /= 1E9;
00204 seconds += ts.tv_sec;
00205 }
00206
00207 long getSeconds() const { return ts.tv_sec; }
00208 void setSeconds(long v) { ts.tv_nsec = 0; ts.tv_sec = v; }
00209 void addSeconds(long v) { ts.tv_sec += v; }
00210
00211 long getMilliSeconds() const
00212 {
00213 return ts.tv_sec * 1000 + ts.tv_nsec / 1000000L;
00214 }
00215
00216 void setMilliSeconds(long v)
00217 {
00218 ldiv_t d = ldiv(v, 1000);
00219 ts.tv_sec = d.quot;
00220 ts.tv_nsec = d.rem * 1000000L;
00221 }
00222
00223 void addMilliSeconds(long v)
00224 {
00225 Time t;
00226 t.setMilliSeconds(v);
00227 this->operator+=(t);
00228 }
00229
00230 long getMicroSeconds() const
00231 {
00232 return ts.tv_sec * 1000000L + ts.tv_nsec / 1000;
00233 }
00234
00235 void setMicroSeconds(long v)
00236 {
00237 ldiv_t d = ldiv(v, 1000000L);
00238 ts.tv_sec = d.quot;
00239 ts.tv_nsec = d.rem * 1000;
00240 }
00241
00242 void addMicroSeconds(long v)
00243 {
00244 Time t;
00245 t.setMicroSeconds(v);
00246 this->operator+=(t);
00247 }
00248
00249 long getNanoSeconds() const
00250 {
00251 return ts.tv_sec * 1000000000L + ts.tv_nsec;
00252 }
00253
00254 void setNanoSeconds(long v)
00255 {
00256 ldiv_t d = ldiv(v, 1000000000L);
00257 ts.tv_sec = d.quot;
00258 ts.tv_nsec = d.rem;
00259 }
00260
00261 void addNanoSeconds(long v)
00262 {
00263 Time t;
00264 t.setNanoSeconds(v);
00265 this->operator+=(t);
00266 }
00267
00268 private:
00269 friend class Condition;
00270
00271 timespec ts;
00272
00273 void addAdjust()
00274 {
00275 if(ts.tv_nsec < 1000000000L) return;
00276 ts.tv_nsec -= 1000000000L;
00277 ++ts.tv_sec;
00278 }
00279
00280 void subAdjust()
00281 {
00282 if(ts.tv_nsec >= 0) return;
00283 ts.tv_nsec += 1000000000L;
00284 --ts.tv_sec;
00285 }
00286 };
00287
00288 namespace Text
00289 {
00290 string toString(const Time &);
00291 }
00292 }
00293 }
00294
00295 namespace std
00296 {
00297 ostream &operator<<(ostream &, const Archon::Utilities::Time &);
00298 }
00299
00300 #endif // ARCHON_UTILITIES_TIME_H