// timer class implementation ----------------------------------------------// // (C) Copyright Beman Dawes 1994-98. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. /// Portability warning: this implementation depends on std::clock() returning /// elapsed time, and CLOCKS_PER_SEC being reasonably large. Those /// requirements are not met by all operating systems. // Revision History // 25 Sep 99 elapsed_max() and elapsed_min() added (John_Maddock) // 16 Jul 99 Second beta // 6 Jul 99 Initial boost version #include #include #ifdef _WIN32 // // Win32 implemention of timer class, uses NT's // high performance counters rather than clock(). // timer resolution should be sub micro-second. // #define NOMINMAX #include #include #include namespace boost { #if defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 clock_t; #else typedef long long clock_t; #endif class timer::_timer { public: clock_t start_time; static clock_t freq; static clock_t max_count; }; // // _timer::freq holds the number of ticks per second: clock_t timer::_timer::freq = 0; // // _timer::max_count holds the equivalent of numeric_limits<__int64>::max(), // neither Borland nor Microsoft seem to specialise numeric_limits on // __int64 - in other words this is a workaround: clock_t timer::_timer::max_count = (~(clock_t)0) & ~((clock_t)1 << 63); timer::timer() : _imp( new _timer ) { if(0 == _timer::freq) if(0 == QueryPerformanceFrequency(reinterpret_cast(&_timer::freq))) { // // if QueryPerformanceFrequency fails then the timer is not available, // I don't know of any systems where this is the case, but we'd better // check anyway.... char* lpMsgBuf = 0; FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); std::string msg(lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); throw std::runtime_error(msg); } QueryPerformanceCounter(reinterpret_cast(&(_imp->start_time))); } timer::timer( const timer& src ) : _imp( new _timer ) { _imp->start_time = src._imp->start_time; } timer::~timer(){} void timer::restart() { QueryPerformanceCounter(reinterpret_cast(&(_imp->start_time))); } timer& timer::operator=( const timer& src ) { _imp->start_time = src._imp->start_time; return *this; } double timer::elapsed() const { clock_t t; QueryPerformanceCounter(reinterpret_cast(&t)); return (double)(t - _imp->start_time) / (double)_timer::freq; } double timer::elapsed_max() const { return (double(_timer::max_count) - double(_imp->start_time)) / double(_timer::freq); } double timer::elapsed_min() const { return double(1) / double(_timer::freq); } } // namespace boost #else #include namespace std {} /// cope with implementations which do not yet using namespace std; /// place the functions in namespace std /// Yes, this is ugly, but it is also the real world namespace boost { class timer::_timer { public: clock_t start_time; }; timer::timer() : _imp( new _timer ) { _imp->start_time = clock(); } timer::timer( const timer& src ) : _imp( new _timer ) { _imp->start_time = src._imp->start_time; } timer::~timer(){} void timer::restart() { _imp->start_time = clock(); } timer& timer::operator=( const timer& src ) { _imp->start_time = src._imp->start_time; return * this; } double timer::elapsed() const { return double(clock() - _imp->start_time) / CLOCKS_PER_SEC; } double timer::elapsed_max() const { return (double(std::numeric_limits::max()) - double(_imp->start_time)) / double(CLOCKS_PER_SEC); } double timer::elapsed_min() const { return double(1)/double(CLOCKS_PER_SEC); } } // namespace boost #endif <