aboutsummaryrefslogtreecommitdiff
path: root/tools/debugserver/source/DNBTimer.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugserver/source/DNBTimer.h')
-rw-r--r--tools/debugserver/source/DNBTimer.h163
1 files changed, 163 insertions, 0 deletions
diff --git a/tools/debugserver/source/DNBTimer.h b/tools/debugserver/source/DNBTimer.h
new file mode 100644
index 000000000000..ca56e30c7090
--- /dev/null
+++ b/tools/debugserver/source/DNBTimer.h
@@ -0,0 +1,163 @@
+//===-- DNBTimer.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Created by Greg Clayton on 12/13/07.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __DNBTimer_h__
+#define __DNBTimer_h__
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <memory>
+#include "DNBDefs.h"
+#include "PThreadMutex.h"
+
+class DNBTimer
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ DNBTimer (bool threadSafe) :
+ m_mutexAP()
+ {
+ if (threadSafe)
+ m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
+ Reset();
+ }
+
+ DNBTimer (const DNBTimer& rhs) :
+ m_mutexAP()
+ {
+ // Create a new mutex to make this timer thread safe as well if
+ // the timer we are copying is thread safe
+ if (rhs.IsThreadSafe())
+ m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
+ m_timeval = rhs.m_timeval;
+ }
+
+ DNBTimer& operator= (const DNBTimer& rhs)
+ {
+ // Create a new mutex to make this timer thread safe as well if
+ // the timer we are copying is thread safe
+ if (rhs.IsThreadSafe())
+ m_mutexAP.reset(new PThreadMutex(PTHREAD_MUTEX_RECURSIVE));
+ m_timeval = rhs.m_timeval;
+ return *this;
+ }
+
+ ~DNBTimer ()
+ {
+ }
+
+ bool
+ IsThreadSafe() const
+ {
+ return m_mutexAP.get() != NULL;
+ }
+ //------------------------------------------------------------------
+ // Reset the time value to now
+ //------------------------------------------------------------------
+ void
+ Reset ()
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
+ gettimeofday (&m_timeval, NULL);
+ }
+ //------------------------------------------------------------------
+ // Get the total mircoseconds since Jan 1, 1970
+ //------------------------------------------------------------------
+ uint64_t
+ TotalMicroSeconds () const
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
+ return (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;
+ }
+
+ void
+ GetTime (uint64_t& sec, uint32_t& usec) const
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
+ sec = m_timeval.tv_sec;
+ usec = m_timeval.tv_usec;
+ }
+ //------------------------------------------------------------------
+ // Return the number of microseconds elapsed between now and the
+ // m_timeval
+ //------------------------------------------------------------------
+ uint64_t
+ ElapsedMicroSeconds (bool update)
+ {
+ PTHREAD_MUTEX_LOCKER (locker, m_mutexAP.get());
+ struct timeval now;
+ gettimeofday (&now, NULL);
+ uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
+ uint64_t this_usec = (uint64_t)(m_timeval.tv_sec) * 1000000ull + (uint64_t)m_timeval.tv_usec;
+ uint64_t elapsed = now_usec - this_usec;
+ // Update the timer time value if requeseted
+ if (update)
+ m_timeval = now;
+ return elapsed;
+ }
+
+ static uint64_t GetTimeOfDay()
+ {
+ struct timeval now;
+ gettimeofday (&now, NULL);
+ uint64_t now_usec = (uint64_t)(now.tv_sec) * 1000000ull + (uint64_t)now.tv_usec;
+ return now_usec;
+ }
+
+ static void OffsetTimeOfDay (struct timespec* ts, __darwin_time_t sec_offset = 0, long nsec_offset = 0)
+ {
+ if (ts == NULL)
+ return;
+ // Get the current time in a timeval structure
+ struct timeval now;
+ gettimeofday (&now, NULL);
+ // Morph it into a timespec
+ TIMEVAL_TO_TIMESPEC(&now, ts);
+ // Offset the timespec if requested
+ if (sec_offset != 0 || nsec_offset != 0)
+ {
+ // Offset the nano seconds
+ ts->tv_nsec += nsec_offset;
+ // Offset the seconds taking into account a nano-second overflow
+ ts->tv_sec = ts->tv_sec + ts->tv_nsec / 1000000000 + sec_offset;
+ // Trim the nanoseconds back there was an overflow
+ ts->tv_nsec = ts->tv_nsec % 1000000000;
+ }
+ }
+ static bool TimeOfDayLaterThan (struct timespec &ts)
+ {
+ struct timespec now;
+ OffsetTimeOfDay(&now);
+ if (now.tv_sec > ts.tv_sec)
+ return true;
+ else if (now.tv_sec < ts.tv_sec)
+ return false;
+ else
+ {
+ if (now.tv_nsec > ts.tv_nsec)
+ return true;
+ else
+ return false;
+ }
+ }
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from DNBTimer can see and modify these
+ //------------------------------------------------------------------
+ std::unique_ptr<PThreadMutex> m_mutexAP;
+ struct timeval m_timeval;
+};
+
+#endif // #ifndef __DNBTimer_h__