diff options
Diffstat (limited to 'tools/debugserver/source/DNBTimer.h')
-rw-r--r-- | tools/debugserver/source/DNBTimer.h | 163 |
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__ |