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