| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- // CPerfTimer - a simple Win32 performance counter wrapper
- // by Dean Wyant [email protected]
- /*
- This class is simple to use. Just declare a variable(s) as type CPerfTimer,
- call Start() to start timimg and call Stop() to stop timimg. You can pause a
- timer by calling Stop() and then you can call Start() to resume. Retrieve the
- elapsed time by calling an Elapsed..() function. Assignment, addition,
- subtraction and comparison are supported. There are a few information calls
- available also. All calls except Start and Stop can be performed on a timer
- without stopping it.
-
- */
- #ifndef __PERFTIMER_H__
- #define __PERFTIMER_H__
- class CPerfTimer
- {
- public:
- CPerfTimer(BOOL bStart = FALSE) {Init(bStart);}
- CPerfTimer(const CPerfTimer& Src);
- virtual ~CPerfTimer() {;}
- void Start(BOOL bReset = FALSE); // Start from current value or optionally from 0
- void Stop(); // Stop timing. Use Start afterwards to continue.
-
- BOOL IsRunning(); // Returns FALSE if stopped.
-
- BOOL IsSupported(); // Returns FALSE if performance counter not supported.
- // Call after constructing at least one CPerfTimer
- const double Resolution(); // Returns timer resolution in seconds
- const double Resolutionms(); // Returns timer resolution in milliseconds
- const double Resolutionus(); // Returns timer resolution in microseconds
-
- const double Elapsed(); // Returns elapsed time in seconds
- const double Elapsedms(); // Returns elapsed time in milliseconds
- const double Elapsedus(); // Returns elapsed time in microseconds
- const CPerfTimer& operator=(const CPerfTimer& Src); // Assignment operator
- // Math operators
- CPerfTimer operator+(const CPerfTimer& Src) const;
- CPerfTimer operator-(const CPerfTimer& Src) const;
- const CPerfTimer& operator+=(const CPerfTimer& Src);
- const CPerfTimer& operator-=(const CPerfTimer& Src);
- // For time in seconds
- CPerfTimer operator+(const double Secs) const;
- CPerfTimer operator-(const double Secs) const;
- const CPerfTimer& operator+=(const double Secs);
- const CPerfTimer& operator-=(const double Secs);
- // Boolean comparison operators
- BOOL operator<(const CPerfTimer& Src);
- BOOL operator>(const CPerfTimer& Src);
- BOOL operator<=(const CPerfTimer& Src);
- BOOL operator>=(const CPerfTimer& Src);
- // For time in seconds
- BOOL operator<(const double Secs);
- BOOL operator>(const double Secs);
- BOOL operator<=(const double Secs);
- BOOL operator>=(const double Secs);
- virtual void Lock() const {;} // Override for thread safe operation
- virtual void Unlock() const {;} // Override for thread safe operation
- protected:
- void Init(BOOL bStart);
- void Copy(const CPerfTimer& Src);
- private:
- __int64 m_Start;
- static __int64 m_Freq; // does not change while system is running
- static __int64 m_Adjust; // Adjustment time it takes to Start and Stop
- };
- class CPerfTimerT : public CPerfTimer
- { // You only need to use types of this class if a timer is going to be shared between threads
- public:
- CPerfTimerT(BOOL bStart = FALSE)
- {
- m_hMutex = CreateMutex(NULL, FALSE, _T(""));
- Init(bStart);
- }
- CPerfTimerT(const CPerfTimerT& Src)
- {
- m_hMutex = CreateMutex(NULL,FALSE,_T(""));
- Copy(Src);
- }
- CPerfTimerT(const CPerfTimer& Src)
- {
- m_hMutex = CreateMutex(NULL,FALSE,_T(""));
- Copy(Src);
- }
- virtual ~CPerfTimerT()
- { CloseHandle(m_hMutex); }
- const CPerfTimerT& operator=(const CPerfTimerT& Src) // Assignment operator
- {
- Copy(Src);
- return *this;
- }
-
- virtual void Lock() const { WaitForSingleObject(m_hMutex,10000); }
- virtual void Unlock() const { ReleaseMutex(m_hMutex); }
- private:
- HANDLE m_hMutex;
- };
- inline void CPerfTimer::Init(BOOL bStart)
- {
- if (!m_Freq)
- { // Initialization should only run once
- QueryPerformanceFrequency((LARGE_INTEGER *)&m_Freq);
- if (!m_Freq)
- m_Freq = 1; // Timer will be useless but will not cause divide by zero
- m_Start = 0;
- m_Adjust = 0;
- Start(); // Time a Stop
- Stop();
- m_Adjust = m_Start;
- }
- // This is the only part that normally runs
- m_Start = 0;
- if (bStart)
- Start();
- }
- inline CPerfTimer::CPerfTimer(const CPerfTimer& Src)
- {
- Copy(Src);
- }
- inline void CPerfTimer::Copy(const CPerfTimer& Src)
- {
- if (&Src == this)
- return; // avoid deadlock if someone tries to copy it to itself
- Src.Lock();
- Lock();
- m_Start = Src.m_Start;
- Unlock();
- Src.Unlock();
- }
- inline void CPerfTimer::Start(BOOL bReset)
- { // Start from current value or optionally from 0
- __int64 i;
- QueryPerformanceCounter((LARGE_INTEGER *)&i);
- Lock();
- if ((!bReset) && (m_Start < 0))
- m_Start += i; // We are starting with an accumulated time
- else
- m_Start = i; // Starting from 0
- Unlock();
- }
- inline void CPerfTimer::Stop()
- { // Stop timing. Use Start afterwards to continue
- Lock();
- if (m_Start <= 0)
- {
- Unlock();
- return; // Was not running
- }
- __int64 i;
- QueryPerformanceCounter((LARGE_INTEGER *)&i);
- m_Start += -i; // Stopped timer keeps elapsed timer ticks as a negative
- if (m_Start < m_Adjust) // Do not overflow
- m_Start -= m_Adjust; // Adjust for time timer code takes to run
- else
- m_Start = 0; // Stop must have been called directly after Start
- Unlock();
- }
- inline BOOL CPerfTimer::IsRunning()
- { // Returns FALSE if stopped.
- Lock();
- BOOL bRet = (m_Start > 0); // When < 0, holds elpased clicks
- Unlock();
- return bRet;
- }
- inline const double CPerfTimer::Elapsed()
- { // Returns elapsed time in seconds
- CPerfTimer Result(*this);
- Result.Stop();
- return (double)(-Result.m_Start)/(double)m_Freq;
- }
- inline const double CPerfTimer::Elapsedms()
- { // Returns elapsed time in milliseconds
- CPerfTimer Result(*this);
- Result.Stop();
- return (-Result.m_Start*1000.0)/(double)m_Freq;
- }
- inline const double CPerfTimer::Elapsedus()
- { // Returns elapsed time in microseconds
- CPerfTimer Result(*this);
- Result.Stop();
- return (-Result.m_Start * 1000000.0)/(double)m_Freq;
- }
- // Assignment operator
- inline const CPerfTimer& CPerfTimer::operator=(const CPerfTimer& Src)
- {
- Copy(Src);
- return *this;
- }
- // Math operators
- inline CPerfTimer CPerfTimer::operator+(const CPerfTimer& Src) const
- {
- CPerfTimer Result(*this);
- Result += Src;
- return Result;
- }
- inline CPerfTimer CPerfTimer::operator-(const CPerfTimer& Src) const
- {
- CPerfTimer Result(*this);
- Result -= Src;
- return Result;
- }
- inline const CPerfTimer& CPerfTimer::operator+=(const CPerfTimer& Src)
- {
- CPerfTimer SrcStop(Src); // Temp is necessary in case Src is not stopped
- SrcStop.Stop();
- Lock();
- m_Start += SrcStop.m_Start;
- Unlock();
- return *this;
- }
- inline const CPerfTimer& CPerfTimer::operator-=(const CPerfTimer& Src)
- {
- CPerfTimer SrcStop(Src); // Temp is necessary in case Src is not stopped
- SrcStop.Stop();
- Lock();
- m_Start -= SrcStop.m_Start;
- Unlock();
- return *this;
- }
- // For time in seconds
- inline CPerfTimer CPerfTimer::operator+(const double Secs) const
- {
- CPerfTimer Result(*this);
- Result += Secs;
- return Result;
- }
- inline CPerfTimer CPerfTimer::operator-(const double Secs) const
- {
- CPerfTimer Result(*this);
- Result += Secs;
- return Result;
- }
- inline const CPerfTimer& CPerfTimer::operator+=(const double Secs)
- {
- Lock();
- m_Start -= (__int64)(Secs*(double)m_Freq);
- Unlock();
- return *this;
- }
- inline const CPerfTimer& CPerfTimer::operator-=(const double Secs)
- {
- Lock();
- m_Start += (__int64)(Secs*(double)m_Freq);
- Unlock();
- return *this;
- }
- // Boolean comparison operators
- inline BOOL CPerfTimer::operator<(const CPerfTimer& Src)
- {
- BOOL bRet;
- CPerfTimer Temp(Src);
- Lock();
- if (m_Start <= 0)
- {
- Temp.Stop();
- bRet = (m_Start > Temp.m_Start);
- Unlock();
- return bRet;
- }
- else
- if (Temp.m_Start > 0)
- {
- bRet = (m_Start < Temp.m_Start);
- Unlock();
- return bRet;
- }
- else
- {
- Unlock();
- CPerfTimer ThisStop(*this);
- ThisStop.Stop();
- return (ThisStop.m_Start > Temp.m_Start);
- }
- }
- inline BOOL CPerfTimer::operator>(const CPerfTimer& Src)
- {
- BOOL bRet;
- CPerfTimer Temp(Src);
- Lock();
- if (m_Start <= 0)
- {
- Temp.Stop();
- bRet = (m_Start < Temp.m_Start);
- Unlock();
- return bRet;
- }
- else
- if (Temp.m_Start > 0)
- {
- bRet = (m_Start > Temp.m_Start);
- Unlock();
- return bRet;
- }
- else
- {
- Unlock();
- CPerfTimer ThisStop(*this);
- ThisStop.Stop();
- return (ThisStop.m_Start < Temp.m_Start);
- }
- }
- inline BOOL CPerfTimer::operator<=(const CPerfTimer& Src)
- {
- return !(*this > Src);
- }
- inline BOOL CPerfTimer::operator>=(const CPerfTimer& Src)
- {
- return !(*this < Src);
- }
- // For time in seconds
- inline BOOL CPerfTimer::operator<(const double Secs)
- {
- BOOL bRet;
- Lock();
- if (m_Start <= 0)
- {
- bRet = (m_Start > (__int64)(-Secs*(double)m_Freq));
- Unlock();
- return bRet;
- }
- else
- {
- Unlock();
- CPerfTimer ThisStop(*this);
- ThisStop.Stop();
- return (ThisStop.m_Start > (__int64)(-Secs*(double)m_Freq));
- }
- }
- inline BOOL CPerfTimer::operator>(const double Secs)
- {
- BOOL bRet;
- Lock();
- if (m_Start <= 0)
- {
- bRet = (m_Start < (__int64)(-Secs*(double)m_Freq));
- Unlock();
- return bRet;
- }
- else
- {
- Unlock();
- CPerfTimer ThisStop(*this);
- ThisStop.Stop();
- return (ThisStop.m_Start < (__int64)(-Secs*(double)m_Freq));
- }
- }
- inline BOOL CPerfTimer::operator<=(const double Secs)
- {
- return !(*this > Secs);
- }
- inline BOOL CPerfTimer::operator>=(const double Secs)
- {
- return !(*this < Secs);
- }
- #endif //__PERFTIMER_H__
|