// File: timer.cpp // A simple high-precision, platform independent timer class. #include #include #include #include #include "timer.h" #if defined(WIN32) #include #elif defined(_XBOX) #include #endif unsigned long long timer::g_init_ticks; unsigned long long timer::g_freq; double timer::g_inv_freq; #if defined(WIN32) || defined(_XBOX) inline void query_counter(timer_ticks *pTicks) { QueryPerformanceCounter(reinterpret_cast(pTicks)); } inline void query_counter_frequency(timer_ticks *pTicks) { QueryPerformanceFrequency(reinterpret_cast(pTicks)); } #elif defined(__GNUC__) #include inline void query_counter(timer_ticks *pTicks) { struct timeval cur_time; gettimeofday(&cur_time, NULL); *pTicks = static_cast(cur_time.tv_sec)*1000000ULL + static_cast(cur_time.tv_usec); } inline void query_counter_frequency(timer_ticks *pTicks) { *pTicks = 1000000; } #endif timer::timer() : m_start_time(0), m_stop_time(0), m_started(false), m_stopped(false) { if (!g_inv_freq) init(); } timer::timer(timer_ticks start_ticks) { if (!g_inv_freq) init(); m_start_time = start_ticks; m_started = true; m_stopped = false; } void timer::start(timer_ticks start_ticks) { m_start_time = start_ticks; m_started = true; m_stopped = false; } void timer::start() { query_counter(&m_start_time); m_started = true; m_stopped = false; } void timer::stop() { assert(m_started); query_counter(&m_stop_time); m_stopped = true; } double timer::get_elapsed_secs() const { assert(m_started); if (!m_started) return 0; timer_ticks stop_time = m_stop_time; if (!m_stopped) query_counter(&stop_time); timer_ticks delta = stop_time - m_start_time; return delta * g_inv_freq; } timer_ticks timer::get_elapsed_us() const { assert(m_started); if (!m_started) return 0; timer_ticks stop_time = m_stop_time; if (!m_stopped) query_counter(&stop_time); timer_ticks delta = stop_time - m_start_time; return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; } void timer::init() { if (!g_inv_freq) { query_counter_frequency(&g_freq); g_inv_freq = 1.0f / g_freq; query_counter(&g_init_ticks); } } timer_ticks timer::get_init_ticks() { if (!g_inv_freq) init(); return g_init_ticks; } timer_ticks timer::get_ticks() { if (!g_inv_freq) init(); timer_ticks ticks; query_counter(&ticks); return ticks - g_init_ticks; } double timer::ticks_to_secs(timer_ticks ticks) { if (!g_inv_freq) init(); return ticks * g_inv_freq; }