blob: ac69d9a36a1a9e2e599ab41733374957a9a66c90 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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>
Greg Claytone01e07b2013-04-18 18:10:51 +000019#include "DNBDefs.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#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 //------------------------------------------------------------------
Greg Claytone01e07b2013-04-18 18:10:51 +0000158 STD_UNIQUE_PTR(PThreadMutex) m_mutexAP;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 struct timeval m_timeval;
160};
161
162#endif // #ifndef __DNBTimer_h__