1 // hrtimer.h - originally written and placed in the public domain by Wei Dai 2 3 /// \file hrtimer.h 4 /// \brief Classes for timers 5 6 #ifndef CRYPTOPP_HRTIMER_H 7 #define CRYPTOPP_HRTIMER_H 8 9 #include "config.h" 10 11 #if !defined(HIGHRES_TIMER_AVAILABLE) || (defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE)) 12 #include <time.h> 13 #endif 14 15 NAMESPACE_BEGIN(CryptoPP) 16 17 #ifdef HIGHRES_TIMER_AVAILABLE 18 /// \brief TimerWord is a 64-bit word 19 typedef word64 TimerWord; 20 #else 21 /// \brief TimerWord is a clock_t 22 typedef clock_t TimerWord; 23 #endif 24 25 /// \brief Base class for timers 26 /// \sa ThreadUserTimer, Timer 27 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase 28 { 29 public: 30 /// \brief Unit of measure 31 /// \details Unit selects the unit of measure as returned by functions 32 /// ElapsedTimeAsDouble() and ElapsedTime(). 33 /// \sa ElapsedTimeAsDouble, ElapsedTime 34 enum Unit { 35 /// \brief Timer unit is seconds 36 /// \details All timers support seconds 37 SECONDS = 0, 38 /// \brief Timer unit is milliseconds 39 /// \details All timers support milliseconds 40 MILLISECONDS, 41 /// \brief Timer unit is microseconds 42 /// \details The timer requires hardware support microseconds 43 MICROSECONDS, 44 /// \brief Timer unit is nanoseconds 45 /// \details The timer requires hardware support nanoseconds 46 NANOSECONDS 47 }; 48 49 /// \brief Construct a TimerBase 50 /// \param unit the unit of measure 51 /// \param stuckAtZero flag TimerBase(Unit unit,bool stuckAtZero)52 TimerBase(Unit unit, bool stuckAtZero) 53 : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) 54 , m_start(0), m_last(0) {} 55 56 /// \brief Retrieve the current timer value 57 /// \return the current timer value 58 virtual TimerWord GetCurrentTimerValue() =0; 59 60 /// \brief Retrieve ticks per second 61 /// \return ticks per second 62 /// \details TicksPerSecond() is not the timer resolution. It is a 63 /// conversion factor into seconds. 64 virtual TimerWord TicksPerSecond() =0; 65 66 /// \brief Start the timer 67 void StartTimer(); 68 69 /// \brief Retrieve the elapsed time 70 /// \return the elapsed time as a double 71 /// \details The return value of ElapsedTimeAsDouble() depends upon 72 /// the Unit selected during construction of the timer. For example, 73 /// if <tt>Unit = SECONDS</tt> and ElapsedTimeAsDouble() returns 3, 74 /// then the timer has run for 3 seconds. If 75 /// <tt>Unit = MILLISECONDS</tt> and ElapsedTimeAsDouble() returns 76 /// 3000, then the timer has run for 3 seconds. 77 /// \sa Unit, ElapsedTime 78 double ElapsedTimeAsDouble(); 79 80 /// \brief Retrieve the elapsed time 81 /// \return the elapsed time as an unsigned long 82 /// \details The return value of ElapsedTime() depends upon the 83 /// Unit selected during construction of the timer. For example, if 84 /// <tt>Unit = SECONDS</tt> and ElapsedTime() returns 3, then 85 /// the timer has run for 3 seconds. If <tt>Unit = MILLISECONDS</tt> 86 /// and ElapsedTime() returns 3000, then the timer has run for 3 87 /// seconds. 88 /// \sa Unit, ElapsedTimeAsDouble 89 unsigned long ElapsedTime(); 90 91 private: 92 double ConvertTo(TimerWord t, Unit unit); 93 94 Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX 95 bool m_stuckAtZero, m_started; 96 TimerWord m_start, m_last; 97 }; 98 99 /// \brief Measure CPU time spent executing instructions of this thread 100 /// \details ThreadUserTimer requires support of the OS. On Unix-based it 101 /// reports process time. On Windows NT or later desktops and servers it 102 /// reports thread times with performance counter precision.. On Windows 103 /// Phone and Windows Store it reports wall clock time with performance 104 /// counter precision. On all others it reports wall clock time. 105 /// \note ThreadUserTimer only works correctly on Windows NT or later 106 /// desktops and servers. 107 /// \sa Timer 108 class ThreadUserTimer : public TimerBase 109 { 110 public: 111 /// \brief Construct a ThreadUserTimer 112 /// \param unit the unit of measure 113 /// \param stuckAtZero flag TimerBase(unit,stuckAtZero)114 ThreadUserTimer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} 115 TimerWord GetCurrentTimerValue(); 116 TimerWord TicksPerSecond(); 117 }; 118 119 /// \brief High resolution timer 120 /// \sa ThreadUserTimer 121 class CRYPTOPP_DLL Timer : public TimerBase 122 { 123 public: 124 /// \brief Construct a Timer 125 /// \param unit the unit of measure 126 /// \param stuckAtZero flag TimerBase(unit,stuckAtZero)127 Timer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} 128 TimerWord GetCurrentTimerValue(); 129 TimerWord TicksPerSecond(); 130 }; 131 132 NAMESPACE_END 133 134 #endif 135