00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <base/Time>
00026
00027 #include <base/Serializer>
00028
00029 #include <iostream>
00030
00031 extern "C" {
00032 #include <sys/time.h>
00033 #include <sys/uio.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036 }
00037
00038 using base::Time;
00039
00040
00041 Time* Time::time=0;
00042 long Time::baseSecs;
00043 long Time::baseMicros;
00044 Time Time::lastNow;
00045 long Time::resolution;
00046
00047
00048 Time::Time()
00049 {
00050 const SInt minResolution = 20000;
00051
00052 if (time==0) {
00053
00054 time = this;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 struct timeval now;
00068 gettimeofday(&now,0);
00069 baseSecs = now.tv_sec;
00070 baseMicros = now.tv_usec;
00071
00072 usleep(1);
00073
00074 gettimeofday(&now,0);
00075 resolution = (now.tv_usec - baseMicros) + microsPerSec*(now.tv_sec - baseSecs);
00076
00077 if (resolution > minResolution) {
00078
00079
00080 gettimeofday(&now,0);
00081 baseSecs = now.tv_sec;
00082 baseMicros = now.tv_usec;
00083 usleep(1);
00084
00085 gettimeofday(&now,0);
00086 resolution = (now.tv_usec - baseMicros) + microsPerSec*(now.tv_sec - baseSecs);
00087
00088 if (resolution > minResolution) {
00089 Logln("WARNING: time resolution is only " << resolution << "us. It may be too coarse.");
00090 }
00091
00092 }
00093
00094 }
00095
00096 secs=micros=0;
00097 }
00098
00099
00100
00101 Time::Time(Real secs)
00102 {
00103 this->secs = long(secs);
00104 micros = long((secs-Real(this->secs))*Real(microsPerSec));
00105 }
00106
00107
00108 Time::~Time()
00109 {
00110 if (this==time) {
00111
00112
00113 time=0;
00114 }
00115 }
00116
00117
00118 const Time& Time::now()
00119 {
00120 struct timeval now;
00121 gettimeofday(&now,0);
00122 lastNow.secs = now.tv_sec - baseSecs;
00123 lastNow.micros = now.tv_usec - baseMicros;
00124 if (lastNow.micros < 0) {
00125 lastNow.micros += microsPerSec;
00126 lastNow.secs--;
00127 }
00128 return lastNow;
00129 }
00130
00131
00132 bool Time::less(const Time& t1, const Time& t2)
00133 {
00134 if (t1.secs < t2.secs)
00135 return true;
00136 else
00137 if (t1.secs == t2.secs)
00138 return (t1.micros < t2.micros);
00139
00140 return false;
00141 }
00142
00143
00144 bool Time::greater(const Time& t1, const Time& t2)
00145 {
00146 if (t1.secs > t2.secs)
00147 return true;
00148 else
00149 if (t1.secs == t2.secs)
00150 return (t1.micros > t2.micros);
00151
00152 return false;
00153 }
00154
00155
00156 void Time::sleep(const Time& t)
00157 {
00158 if (t.secs > 0) ::sleep(t.secs);
00159 if (t.micros > 0) usleep(t.micros);
00160 }
00161
00162
00163 void Time::sleep(long secs, long micros)
00164 {
00165 sleep(Time(secs,micros));
00166 }
00167
00168
00169 void Time::normalize()
00170 {
00171 if (secs > 0) {
00172 while (micros < 0) {
00173 micros+= microsPerSec;
00174 secs--;
00175 }
00176 while (micros >= microsPerSec) {
00177 micros-= microsPerSec;
00178 secs++;
00179 }
00180 }
00181
00182 if (secs == 0) {
00183 while (micros >= microsPerSec) {
00184 micros-= microsPerSec;
00185 secs++;
00186 }
00187 while (micros <= -microsPerSec) {
00188 micros+= microsPerSec;
00189 secs--;
00190 }
00191 }
00192
00193 if (secs < 0) {
00194 while (micros > 0) {
00195 micros-= microsPerSec;
00196 secs++;
00197 }
00198 while (micros <= -microsPerSec) {
00199 micros+= microsPerSec;
00200 secs--;
00201 }
00202 }
00203
00204 if (secs!=0) {
00205 if ((secs>0) && (micros<0)) {
00206 micros+=microsPerSec;
00207 secs--;
00208 }
00209 if ((secs<0) && (micros>0)) {
00210 micros-=microsPerSec;
00211 secs++;
00212 }
00213 }
00214
00215 }
00216
00217
00218 std::ostream& base::operator<<(std::ostream& out, const Time& t)
00219 {
00220 return out << t.secs << "s:" << t.micros << "us";
00221 }
00222
00223
00224 Time& Time::operator-=(const Time& t)
00225 {
00226 long ds = secs - t.secs;
00227 long dm = micros - t.micros;
00228
00229 Time r(ds,dm);
00230 r.normalize();
00231 *this = r;
00232 return *this;
00233 }
00234
00235
00236 Time& Time::operator+=(const Time& t)
00237 {
00238 long ss = secs + t.secs;
00239 long sm = micros + t.micros;
00240
00241 Time r(ss,sm);
00242 r.normalize();
00243 *this = r;
00244 return *this;
00245 }
00246
00247
00248 Time& Time::operator*=(Real s)
00249 {
00250 Real rs = Real(secs)*s;
00251 long ss = long(rs);
00252 Real ds = rs - ss;
00253
00254 long sm = long( Real(micros)*s );
00255 sm += long( ds*microsPerSec );
00256
00257 Time r(ss,sm);
00258 r.normalize();
00259 *this = r;
00260 return *this;
00261 }
00262
00263
00264 void Time::serialize(Serializer& s)
00265 {
00266 s(LInt(secs),"secs"); s(LInt(micros),"micros");
00267 }
00268
00269