Mercurial > foo_out_sdl
comparison foosdk/sdk/pfc/timers.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 #include "string_base.h" | |
| 4 | |
| 5 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) | |
| 6 | |
| 7 #define PFC_HAVE_PROFILER | |
| 8 | |
| 9 #include <intrin.h> | |
| 10 namespace pfc { | |
| 11 class profiler_static { | |
| 12 public: | |
| 13 profiler_static(const char * p_name); | |
| 14 ~profiler_static(); | |
| 15 void add_time(t_int64 delta) { total_time += delta;num_called++; } | |
| 16 private: | |
| 17 const char * name; | |
| 18 t_uint64 total_time, num_called; | |
| 19 }; | |
| 20 | |
| 21 class profiler_local { | |
| 22 public: | |
| 23 profiler_local(profiler_static * p_owner) { | |
| 24 owner = p_owner; | |
| 25 start = __rdtsc(); | |
| 26 } | |
| 27 ~profiler_local() { | |
| 28 t_int64 end = __rdtsc(); | |
| 29 owner->add_time(end - start); | |
| 30 } | |
| 31 private: | |
| 32 t_int64 start; | |
| 33 profiler_static * owner; | |
| 34 }; | |
| 35 | |
| 36 } | |
| 37 #define profiler(name) \ | |
| 38 static pfc::profiler_static profiler_static_##name(#name); \ | |
| 39 pfc::profiler_local profiler_local_##name(&profiler_static_##name); | |
| 40 | |
| 41 | |
| 42 #endif | |
| 43 | |
| 44 #ifdef _WIN32 | |
| 45 | |
| 46 namespace pfc { | |
| 47 typedef uint64_t tickcount_t; | |
| 48 inline tickcount_t getTickCount() { return GetTickCount64(); } | |
| 49 | |
| 50 class hires_timer { | |
| 51 public: | |
| 52 hires_timer() : m_start() {} | |
| 53 static hires_timer create_and_start() { | |
| 54 hires_timer t; t.start(); return t; | |
| 55 } | |
| 56 void start() { | |
| 57 m_start = g_query(); | |
| 58 } | |
| 59 double query() const { | |
| 60 return _query( g_query() ); | |
| 61 } | |
| 62 double query_reset() { | |
| 63 t_uint64 current = g_query(); | |
| 64 double ret = _query(current); | |
| 65 m_start = current; | |
| 66 return ret; | |
| 67 } | |
| 68 pfc::string8 queryString(unsigned precision = 6) const { | |
| 69 return pfc::format_time_ex( query(), precision ).get_ptr(); | |
| 70 } | |
| 71 private: | |
| 72 double _query(t_uint64 p_val) const { | |
| 73 return (double)( p_val - m_start ) * m_mul; | |
| 74 } | |
| 75 static t_uint64 g_query() { | |
| 76 LARGE_INTEGER val; | |
| 77 if (!QueryPerformanceCounter(&val)) throw pfc::exception_not_implemented(); | |
| 78 return val.QuadPart; | |
| 79 } | |
| 80 static double init_mul() { | |
| 81 return 1.0 / (double)g_query_freq(); | |
| 82 } | |
| 83 static t_uint64 g_query_freq() { | |
| 84 LARGE_INTEGER val; | |
| 85 if (!QueryPerformanceFrequency(&val)) throw pfc::exception_not_implemented(); | |
| 86 PFC_ASSERT(val.QuadPart > 0); | |
| 87 return val.QuadPart; | |
| 88 } | |
| 89 t_uint64 m_start; | |
| 90 double m_mul = init_mul(); | |
| 91 }; | |
| 92 | |
| 93 class lores_timer { | |
| 94 public: | |
| 95 lores_timer() {} | |
| 96 static lores_timer create_and_start() { | |
| 97 lores_timer t; t.start(); return t; | |
| 98 } | |
| 99 void start() { | |
| 100 _start(getTickCount()); | |
| 101 } | |
| 102 | |
| 103 double query() const { | |
| 104 return _query(getTickCount()); | |
| 105 } | |
| 106 double query_reset() { | |
| 107 tickcount_t time = getTickCount(); | |
| 108 double ret = _query(time); | |
| 109 _start(time); | |
| 110 return ret; | |
| 111 } | |
| 112 pfc::string8 queryString(unsigned precision = 3) const { | |
| 113 return pfc::format_time_ex( query(), precision ).get_ptr(); | |
| 114 } | |
| 115 private: | |
| 116 void _start(tickcount_t p_time) { | |
| 117 m_start = p_time; | |
| 118 } | |
| 119 double _query(tickcount_t p_time) const { | |
| 120 return (double)(p_time - m_start) / 1000.0; | |
| 121 } | |
| 122 t_uint64 m_start = 0; | |
| 123 }; | |
| 124 | |
| 125 class media_timer { | |
| 126 typedef DWORD val_t; | |
| 127 static val_t _now() { return timeGetTime(); } | |
| 128 public: | |
| 129 void start() { | |
| 130 _start(_now()); | |
| 131 } | |
| 132 double query() const { | |
| 133 return _query(_now()); | |
| 134 } | |
| 135 double query_reset() { | |
| 136 auto now = _now(); | |
| 137 double ret = _query(now); | |
| 138 _start(now); | |
| 139 return ret; | |
| 140 } | |
| 141 pfc::string8 queryString(unsigned precision = 3) const { | |
| 142 return pfc::format_time_ex(query(), precision).get_ptr(); | |
| 143 } | |
| 144 static media_timer create_and_start() { | |
| 145 media_timer t; t.start(); return t; | |
| 146 } | |
| 147 private: | |
| 148 void _start(val_t t) { m_start = t; } | |
| 149 double _query(val_t t) const { return (t - m_start) / 1000.0; } | |
| 150 val_t m_start = 0; | |
| 151 }; | |
| 152 } | |
| 153 #else // not _WIN32 | |
| 154 | |
| 155 namespace pfc { | |
| 156 | |
| 157 class hires_timer { | |
| 158 public: | |
| 159 hires_timer() : m_start() {} | |
| 160 void start(); | |
| 161 double query() const; | |
| 162 double query_reset(); | |
| 163 pfc::string8 queryString(unsigned precision = 3) const; | |
| 164 | |
| 165 static hires_timer create_and_start() { | |
| 166 hires_timer t; t.start(); return t; | |
| 167 } | |
| 168 private: | |
| 169 double m_start; | |
| 170 }; | |
| 171 | |
| 172 typedef hires_timer lores_timer; | |
| 173 typedef hires_timer media_timer; | |
| 174 | |
| 175 } | |
| 176 | |
| 177 #endif // _WIN32 | |
| 178 | |
| 179 #ifndef _WIN32 | |
| 180 struct timespec; | |
| 181 #endif | |
| 182 | |
| 183 namespace pfc { | |
| 184 uint64_t fileTimeWtoU(uint64_t ft); | |
| 185 uint64_t fileTimeUtoW(uint64_t ft); | |
| 186 #ifndef _WIN32 | |
| 187 uint64_t fileTimeUtoW( timespec const & ts ); | |
| 188 #endif | |
| 189 uint64_t fileTimeNow(); | |
| 190 } |
