Transit Planner  1.0
An experiment on transfer patterns robustness
src/Clock.h
00001 // Copyright 2012 Eugen Sawin <sawine@me73.com>
00002 #ifndef SRC_CLOCK_H_
00003 #define SRC_CLOCK_H_
00004 
00005 #include <cstdint>
00006 #include <ctime>
00007 #include <string>
00008 #include <sstream>
00009 
00010 namespace base {
00011 
00012 class Clock {
00013  public:
00014   typedef int64_t Diff;
00015 
00016   enum Type {
00017     kProcessClock = CLOCK_PROCESS_CPUTIME_ID,
00018     kThreadClock = CLOCK_THREAD_CPUTIME_ID
00019   };
00020 
00021   static const Diff kSecInMin = 60;
00022   static const Diff kMilliInSec = 1000;
00023   static const Diff kMicroInMilli = 1000;
00024   static const Diff kNanoInMicro = 1000;
00025   static const Diff kMicroInSec = kMilliInSec * kMicroInMilli;
00026   static const Diff kMicroInMin = kMicroInSec * kSecInMin;
00027   static constexpr double kMilliInMicro = 1.0 / kMicroInMilli;
00028   static constexpr double kMicroInNano = 1.0 / kNanoInMicro;
00029   static constexpr double kSecInMicro = 1.0 / kMicroInSec;
00030   static constexpr double kMinInMicro = 1.0 / kMicroInMin;
00031 
00032   Clock() {
00033     clock_gettime(kProcessClock, &time_);
00034   }
00035 
00036   explicit Clock(const Type type) {
00037     clock_gettime(type, &time_);
00038   }
00039 
00040   Diff operator-(const Clock& rhs) const {
00041     return (time_.tv_sec - rhs.time_.tv_sec) * kMicroInSec +
00042            (time_.tv_nsec - rhs.time_.tv_nsec) * kMicroInNano;
00043   }
00044 
00045   // Returns the time duration between given times in microseconds.
00046   static Diff Duration(const Clock& beg, const Clock& end) {
00047     return end - beg;
00048   }
00049 
00050   // Returns the string representation of the given time difference.
00051   static std::string DiffStr(const Diff& diff) {
00052     std::stringstream ss;
00053     ss.setf(std::ios::fixed, std::ios::floatfield);
00054     ss.precision(2);
00055     if (diff >= kMicroInMin) {
00056       const double min = diff * kMinInMicro;
00057       ss << min << "min";
00058     } else if (diff >= kMicroInSec) {
00059       const double sec = diff * kSecInMicro;
00060       ss << sec << "s";
00061     } else if (diff >= kMicroInMilli) {
00062       const double milli = diff * kMilliInMicro;
00063       ss << milli << "ms";
00064     } else {
00065       ss << diff << "µs";
00066     }
00067     return ss.str();
00068   }
00069 
00070   // Returns the system time resolution.
00071   // Remark: Usually returns 0µs (1ns), this is however a bad promise and does
00072   // not reflect the (dynamic) underlying clock event resolution.
00073   static Diff Resolution() {
00074     timespec res;
00075     clock_getres(CLOCK_MONOTONIC, &res);
00076     return res.tv_sec * kMicroInSec + res.tv_nsec * kMicroInNano;
00077   }
00078 
00079 
00080  private:
00081   timespec time_;
00082 };
00083 
00084 }  // namespace base
00085 
00086 #endif  // SRC_CLOCK_H_
00087 
 All Classes