Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

hrtimer.cpp

00001 // hrtimer.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "hrtimer.h"
00005 #include "misc.h"
00006 #include <stddef.h>             // for NULL
00007 #include <time.h>
00008 
00009 #if defined(CRYPTOPP_WIN32_AVAILABLE)
00010 #include <windows.h>
00011 #elif defined(CRYPTOPP_UNIX_AVAILABLE)
00012 #include <sys/time.h>
00013 #include <sys/times.h>
00014 #include <unistd.h>
00015 #endif
00016 
00017 #include <assert.h>
00018 
00019 NAMESPACE_BEGIN(CryptoPP)
00020 
00021 double TimerBase::ConvertTo(word64 t, Unit unit)
00022 {
00023         static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
00024 
00025         assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0]));
00026         return (double)t * unitsPerSecondTable[unit] / TicksPerSecond();
00027 }
00028 
00029 void TimerBase::StartTimer()
00030 {
00031         m_start = GetCurrentTimerValue();
00032         m_started = true;
00033 }
00034 
00035 double TimerBase::ElapsedTimeAsDouble()
00036 {
00037         if (m_stuckAtZero)
00038                 return 0;
00039         else if (m_started)
00040                 return ConvertTo(GetCurrentTimerValue() - m_start, m_timerUnit);
00041         else
00042         {
00043                 StartTimer();
00044                 return 0;
00045         }
00046 }
00047 
00048 unsigned long TimerBase::ElapsedTime()
00049 {
00050         double elapsed = ElapsedTimeAsDouble();
00051         assert(elapsed <= ULONG_MAX);
00052         return (unsigned long)elapsed;
00053 }
00054 
00055 word64 ThreadUserTimer::GetCurrentTimerValue()
00056 {
00057 #if defined(CRYPTOPP_WIN32_AVAILABLE)
00058         static bool getCurrentThreadImplemented = true;
00059         if (getCurrentThreadImplemented)
00060         {
00061                 FILETIME now, ignored;
00062                 if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
00063                 {
00064                         DWORD lastError = GetLastError();
00065                         if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
00066                         {
00067                                 getCurrentThreadImplemented = false;
00068                                 goto GetCurrentThreadNotImplemented;
00069                         }
00070                         throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
00071                 }
00072                 return now.dwLowDateTime + ((word64)now.dwHighDateTime << 32);
00073         }
00074 GetCurrentThreadNotImplemented:
00075         return (word64)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
00076 #elif defined(CRYPTOPP_UNIX_AVAILABLE)
00077         tms now;
00078         times(&now);
00079         return now.tms_utime;
00080 #else
00081         return clock();
00082 #endif
00083 }
00084 
00085 word64 ThreadUserTimer::TicksPerSecond()
00086 {
00087 #if defined(CRYPTOPP_WIN32_AVAILABLE)
00088         return 10*1000*1000;
00089 #elif defined(CRYPTOPP_UNIX_AVAILABLE)
00090         static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
00091         return ticksPerSecond;
00092 #else
00093         return CLOCKS_PER_SEC;
00094 #endif
00095 }
00096 
00097 #ifdef HIGHRES_TIMER_AVAILABLE
00098 
00099 word64 Timer::GetCurrentTimerValue()
00100 {
00101 #if defined(CRYPTOPP_WIN32_AVAILABLE)
00102         LARGE_INTEGER now;
00103         if (!QueryPerformanceCounter(&now))
00104                 throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError()));
00105         return now.QuadPart;
00106 #elif defined(CRYPTOPP_UNIX_AVAILABLE)
00107         timeval now;
00108         gettimeofday(&now, NULL);
00109         return (word64)now.tv_sec * 1000000 + now.tv_usec;
00110 #endif
00111 }
00112 
00113 word64 Timer::TicksPerSecond()
00114 {
00115 #if defined(CRYPTOPP_WIN32_AVAILABLE)
00116         static LARGE_INTEGER freq = {0};
00117         if (freq.QuadPart == 0)
00118         {
00119                 if (!QueryPerformanceFrequency(&freq))
00120                         throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
00121         }
00122         return freq.QuadPart;
00123 #elif defined(CRYPTOPP_UNIX_AVAILABLE)
00124         return 1000000;
00125 #endif
00126 }
00127 
00128 #endif
00129 
00130 NAMESPACE_END

Generated on Tue Oct 26 20:20:59 2004 for Crypto++ by  doxygen 1.3.9.1