DNBTimer.h revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
1//===-- DNBTimer.h ----------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Created by Greg Clayton on 12/13/07. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef __DNBTimer_h__ 15#define __DNBTimer_h__ 16 17#include <sys/time.h> 18#include <stdint.h> 19#include <memory> 20#include "PThreadMutex.h" 21 22class DNBTimer 23{ 24public: 25 //------------------------------------------------------------------ 26 // Constructors and Destructors 27 //------------------------------------------------------------------ 28 DNBTimer (bool threadSafe) : 29 m_mutexAP() 30 { 31 if (threadSafe) 32 m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE)); 33 Reset(); 34 } 35 36 DNBTimer (const DNBTimer& rhs) : 37 m_mutexAP() 38 { 39 // Create a new mutex to make this timer thread safe as well if 40 // the timer we are copying is thread safe 41 if (rhs.IsThreadSafe()) 42 m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE)); 43 m_timeval = rhs.m_timeval; 44 } 45 46 DNBTimer& operator= (const DNBTimer& rhs) 47 { 48 // Create a new mutex to make this timer thread safe as well if 49 // the timer we are copying is thread safe 50 if (rhs.IsThreadSafe()) 51 m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE)); 52 m_timeval = rhs.m_timeval; 53 return *this; 54 } 55 56 ~DNBTimer () 57 { 58 } 59 60 bool 61 IsThreadSafe() const 62 { 63 return m_mutexAP.get() != NULL; 64 } 65 //------------------------------------------------------------------ 66 // Reset the time value to now 67 //------------------------------------------------------------------ 68 void 69 Reset () 70 { 71 PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get()); 72 gettimeofday (&m_timeval, NULL); 73 } 74 //------------------------------------------------------------------ 75 // Get the total mircoseconds since Jan 1, 1970 76 //------------------------------------------------------------------ 77 uint64_t 78 TotalMicroSeconds () const 79 { 80 PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get()); 81 return (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec; 82 } 83 84 void 85 GetTime (uint32_t& sec, uint32_t& usec) const 86 { 87 PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get()); 88 sec = m_timeval.tv_sec; 89 usec = m_timeval.tv_usec; 90 } 91 //------------------------------------------------------------------ 92 // Return the number of microseconds elapsed between now and the 93 // m_timeval 94 //------------------------------------------------------------------ 95 uint64_t 96 ElapsedMicroSeconds (bool update) 97 { 98 PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get()); 99 struct timeval now; 100 gettimeofday (&now, NULL); 101 uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec; 102 uint64_t this_usec = (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec; 103 uint64_t elapsed = now_usec - this_usec; 104 // Update the timer time value if requeseted 105 if (update) 106 m_timeval = now; 107 return elapsed; 108 } 109 110 static uint64_t GetTimeOfDay() 111 { 112 struct timeval now; 113 gettimeofday (&now, NULL); 114 uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec; 115 return now_usec; 116 } 117 118 static void OffsetTimeOfDay (struct timespec* ts, __darwin_time_t sec_offset = 0, long nsec_offset = 0) 119 { 120 if (ts == NULL) 121 return; 122 // Get the current time in a timeval structure 123 struct timeval now; 124 gettimeofday (&now, NULL); 125 // Morph it into a timespec 126 TIMEVAL_TO_TIMESPEC(&now, ts); 127 // Offset the timespec if requested 128 if (sec_offset != 0 || nsec_offset != 0) 129 { 130 // Offset the nano seconds 131 ts->tv_nsec += nsec_offset; 132 // Offset the seconds taking into account a nano-second overflow 133 ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset; 134 // Trim the nanoseconds back there was an overflow 135 ts->tv_nsec = ts->tv_nsec % 1000000000; 136 } 137 } 138 static bool TimeOfDayLaterThan (struct timespec &ts) 139 { 140 struct timespec now; 141 OffsetTimeOfDay(&now); 142 if (now.tv_sec > ts.tv_sec) 143 return true; 144 else if (now.tv_sec < ts.tv_sec) 145 return false; 146 else 147 { 148 if (now.tv_nsec > ts.tv_nsec) 149 return true; 150 else 151 return false; 152 } 153 } 154protected: 155 //------------------------------------------------------------------ 156 // Classes that inherit from DNBTimer can see and modify these 157 //------------------------------------------------------------------ 158 std::auto_ptr<PThreadMutex> m_mutexAP; 159 struct timeval m_timeval; 160}; 161 162#endif // #ifndef __DNBTimer_h__ 163