00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #if !defined(_MSC_VER)
00015 #include <sys/time.h>
00016 #else
00017 #include <windows.h>
00018 #endif
00019 #if defined(__APPLE__) && defined(__GNUC__)
00020 #include <mach/mach_time.h>
00021 #endif
00022 #include <time.h>
00023 #include <ctime>
00024 #include "base/logging.h"
00025 #include "base/timer.h"
00026
00027 namespace operations_research {
00028
00029
00030
00031 #if !defined(_MSC_VER)
00032 namespace {
00033 static inline int64 TimevalToUsec(const timeval &tv) {
00034 return static_cast<int64>(1000000) * tv.tv_sec + tv.tv_usec;
00035 }
00036 }
00037 #endif
00038
00039 WallTimer::WallTimer()
00040 : start_usec_(0LL), sum_usec_(0LL), has_started_(false) {}
00041
00042 void WallTimer::Start() {
00043 #if defined(_MSC_VER)
00044 start_usec_ = clock();
00045 #elif defined(__GNUC__)
00046 struct timeval tv;
00047 gettimeofday(&tv, NULL);
00048 start_usec_ = TimevalToUsec(tv);
00049 #endif
00050 has_started_ = true;
00051 }
00052
00053 void WallTimer::Stop() {
00054 if (has_started_) {
00055 #if defined(_MSC_VER)
00056 sum_usec_ += clock() - start_usec_;
00057 #elif defined(__GNUC__)
00058 struct timeval tv;
00059 gettimeofday(&tv, NULL);
00060 sum_usec_ += TimevalToUsec(tv) - start_usec_;
00061 #endif
00062 has_started_ = false;
00063 }
00064 }
00065
00066 bool WallTimer::Reset() {
00067 start_usec_ = 0;
00068 sum_usec_ = 0;
00069 has_started_ = false;
00070 return true;
00071 }
00072
00073 void WallTimer::Restart() {
00074 Reset();
00075 Start();
00076 }
00077
00078 bool WallTimer::IsRunning() const {
00079 return has_started_;
00080 }
00081
00082 int64 WallTimer::GetInMs() const {
00083 #if defined(_MSC_VER)
00084 int64 local_sum_usec = sum_usec_;
00085 if (has_started_) {
00086 local_sum_usec += clock() - start_usec_;
00087 }
00088 return local_sum_usec;
00089 #elif defined(__GNUC__)
00090 static const int64 kMilliSecInMicroSec = 1000LL;
00091 int64 local_sum_usec = sum_usec_;
00092 if (has_started_) {
00093 struct timeval tv;
00094 gettimeofday(&tv, NULL);
00095 local_sum_usec += TimevalToUsec(tv) - start_usec_;
00096 }
00097 return local_sum_usec / kMilliSecInMicroSec;
00098 #endif
00099 }
00100
00101 int64 WallTimer::GetTimeInMicroSeconds() {
00102 #if defined(_MSC_VER)
00103 static const int64 kSecInMicroSec = 1000000LL;
00104 LARGE_INTEGER now;
00105 LARGE_INTEGER freq;
00106
00107 QueryPerformanceCounter(&now);
00108 QueryPerformanceFrequency(&freq);
00109 return now.QuadPart * kSecInMicroSec / freq.QuadPart;
00110 #elif defined(__APPLE__) && defined(__GNUC__)
00111 const int64 kMicroSecondsInNanoSeconds = 1000;
00112 int64 time = mach_absolute_time();
00113 mach_timebase_info_data_t info;
00114 kern_return_t err = mach_timebase_info(&info);
00115 if (err == 0) {
00116 return time / kMicroSecondsInNanoSeconds * info.numer / info.denom;
00117 } else {
00118 return 0;
00119 }
00120 #elif defined(__GNUC__) // Linux
00121 const int64 kSecondInMicroSeconds = 1000000;
00122 const int64 kMicroSecondsInNanoSeconds = 1000;
00123 struct timespec current;
00124 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ¤t);
00125 return current.tv_sec * kSecondInMicroSeconds +
00126 current.tv_nsec / kMicroSecondsInNanoSeconds;
00127 #endif
00128 }
00129
00130 double WallTimer::Get() const {
00131 return GetInMs() / 1000.0;
00132 }
00133
00134
00135 CycleTimer::CycleTimer() : time_in_us_(0), state_(INIT) {}
00136
00137 void CycleTimer::Start() {
00138 DCHECK_EQ(INIT, state_);
00139 state_ = STARTED;
00140 time_in_us_ = WallTimer::GetTimeInMicroSeconds();
00141 }
00142
00143 void CycleTimer::Stop() {
00144 DCHECK_EQ(STARTED, state_);
00145 state_ = STOPPED;
00146 time_in_us_ = WallTimer::GetTimeInMicroSeconds() - time_in_us_;
00147 }
00148
00149 void CycleTimer::Reset() {
00150 state_ = INIT;
00151 time_in_us_ = 0;
00152 }
00153
00154 int64 CycleTimer::GetInUsec() const {
00155 DCHECK_EQ(STOPPED, state_);
00156 return time_in_us_;
00157 }
00158
00159 int64 CycleTimer::GetInMs() const {
00160 const int64 kMsInUsec = 1000;
00161 return GetInUsec() / kMsInUsec;
00162 }
00163 }