1 // File: timer.cpp - Simple high-precision timer class. Supports Win32, X360, and POSIX/Linux 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <assert.h> 5 #include <time.h> 6 7 #include "timer.h" 8 9 #if defined(WIN32) 10 #include <windows.h> 11 #elif defined(_XBOX) 12 #include <xtl.h> 13 #endif 14 15 unsigned long long timer::g_init_ticks; 16 unsigned long long timer::g_freq; 17 double timer::g_inv_freq; 18 19 #if defined(WIN32) || defined(_XBOX) query_counter(timer_ticks * pTicks)20inline void query_counter(timer_ticks *pTicks) 21 { 22 QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(pTicks)); 23 } query_counter_frequency(timer_ticks * pTicks)24inline void query_counter_frequency(timer_ticks *pTicks) 25 { 26 QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(pTicks)); 27 } 28 #elif defined(__GNUC__) 29 #include <sys/timex.h> query_counter(timer_ticks * pTicks)30inline void query_counter(timer_ticks *pTicks) 31 { 32 struct timeval cur_time; 33 gettimeofday(&cur_time, NULL); 34 *pTicks = static_cast<unsigned long long>(cur_time.tv_sec)*1000000ULL + static_cast<unsigned long long>(cur_time.tv_usec); 35 } query_counter_frequency(timer_ticks * pTicks)36inline void query_counter_frequency(timer_ticks *pTicks) 37 { 38 *pTicks = 1000000; 39 } 40 #endif 41 timer()42timer::timer() : 43 m_start_time(0), 44 m_stop_time(0), 45 m_started(false), 46 m_stopped(false) 47 { 48 if (!g_inv_freq) 49 init(); 50 } 51 timer(timer_ticks start_ticks)52timer::timer(timer_ticks start_ticks) 53 { 54 if (!g_inv_freq) 55 init(); 56 57 m_start_time = start_ticks; 58 59 m_started = true; 60 m_stopped = false; 61 } 62 start(timer_ticks start_ticks)63void timer::start(timer_ticks start_ticks) 64 { 65 m_start_time = start_ticks; 66 67 m_started = true; 68 m_stopped = false; 69 } 70 start()71void timer::start() 72 { 73 query_counter(&m_start_time); 74 75 m_started = true; 76 m_stopped = false; 77 } 78 stop()79void timer::stop() 80 { 81 assert(m_started); 82 83 query_counter(&m_stop_time); 84 85 m_stopped = true; 86 } 87 get_elapsed_secs() const88double timer::get_elapsed_secs() const 89 { 90 assert(m_started); 91 if (!m_started) 92 return 0; 93 94 timer_ticks stop_time = m_stop_time; 95 if (!m_stopped) 96 query_counter(&stop_time); 97 98 timer_ticks delta = stop_time - m_start_time; 99 return delta * g_inv_freq; 100 } 101 get_elapsed_us() const102timer_ticks timer::get_elapsed_us() const 103 { 104 assert(m_started); 105 if (!m_started) 106 return 0; 107 108 timer_ticks stop_time = m_stop_time; 109 if (!m_stopped) 110 query_counter(&stop_time); 111 112 timer_ticks delta = stop_time - m_start_time; 113 return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; 114 } 115 init()116void timer::init() 117 { 118 if (!g_inv_freq) 119 { 120 query_counter_frequency(&g_freq); 121 g_inv_freq = 1.0f / g_freq; 122 123 query_counter(&g_init_ticks); 124 } 125 } 126 get_init_ticks()127timer_ticks timer::get_init_ticks() 128 { 129 if (!g_inv_freq) 130 init(); 131 132 return g_init_ticks; 133 } 134 get_ticks()135timer_ticks timer::get_ticks() 136 { 137 if (!g_inv_freq) 138 init(); 139 140 timer_ticks ticks; 141 query_counter(&ticks); 142 return ticks - g_init_ticks; 143 } 144 ticks_to_secs(timer_ticks ticks)145double timer::ticks_to_secs(timer_ticks ticks) 146 { 147 if (!g_inv_freq) 148 init(); 149 150 return ticks * g_inv_freq; 151 } 152 153