Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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 Wed Jul 21 19:15:26 2004 for Crypto++ by doxygen 1.3.7-20040704