#pragma once #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) #define PFC_HAVE_PROFILER #include namespace pfc { class profiler_static { public: profiler_static(const char * p_name); ~profiler_static(); void add_time(t_int64 delta) { total_time += delta;num_called++; } private: const char * name; t_uint64 total_time, num_called; }; class profiler_local { public: profiler_local(profiler_static * p_owner) { owner = p_owner; start = __rdtsc(); } ~profiler_local() { t_int64 end = __rdtsc(); owner->add_time(end - start); } private: t_int64 start; profiler_static * owner; }; } #define profiler(name) \ static pfc::profiler_static profiler_static_##name(#name); \ pfc::profiler_local profiler_local_##name(&profiler_static_##name); #endif #ifdef _WIN32 namespace pfc { #if _WIN32_WINNT >= 0x600 typedef uint64_t tickcount_t; inline tickcount_t getTickCount() { return GetTickCount64(); } #else #define PFC_TICKCOUNT_32BIT typedef uint32_t tickcount_t; inline tickcount_t getTickCount() { return GetTickCount(); } #endif class hires_timer { public: hires_timer() : m_start() {} void start() { m_start = g_query(); } double query() const { return _query( g_query() ); } double query_reset() { t_uint64 current = g_query(); double ret = _query(current); m_start = current; return ret; } pfc::string8 queryString(unsigned precision = 6) const { return pfc::format_time_ex( query(), precision ).get_ptr(); } private: double _query(t_uint64 p_val) const { return (double)( p_val - m_start ) / (double) g_query_freq(); } static t_uint64 g_query() { LARGE_INTEGER val; if (!QueryPerformanceCounter(&val)) throw pfc::exception_not_implemented(); return val.QuadPart; } static t_uint64 g_query_freq() { LARGE_INTEGER val; if (!QueryPerformanceFrequency(&val)) throw pfc::exception_not_implemented(); return val.QuadPart; } t_uint64 m_start; }; class lores_timer { public: lores_timer() : m_start() {} void start() { _start(getTickCount()); } double query() const { return _query(getTickCount()); } double query_reset() { tickcount_t time = getTickCount(); double ret = _query(time); _start(time); return ret; } pfc::string8 queryString(unsigned precision = 3) const { return pfc::format_time_ex( query(), precision ).get_ptr(); } private: void _start(tickcount_t p_time) { #ifdef PFC_TICKCOUNT_32BIT m_last_seen = p_time; #endif m_start = p_time; } double _query(tickcount_t p_time) const { #ifdef PFC_TICKCOUNT_32BIT t_uint64 time = p_time; if (time < (m_last_seen & 0xFFFFFFFF)) time += 0x100000000; m_last_seen = (m_last_seen & 0xFFFFFFFF00000000) + time; return (double)(m_last_seen - m_start) / 1000.0; #else return (double)(p_time - m_start) / 1000.0; #endif } t_uint64 m_start; #ifdef PFC_TICKCOUNT_32BIT mutable t_uint64 m_last_seen; #endif }; } #else // not _WIN32 namespace pfc { class hires_timer { public: hires_timer() : m_start() {} void start(); double query() const; double query_reset(); pfc::string8 queryString(unsigned precision = 3) const; private: double m_start; }; typedef hires_timer lores_timer; } #endif // _WIN32 #ifndef _WIN32 struct timespec; #endif namespace pfc { uint64_t fileTimeWtoU(uint64_t ft); uint64_t fileTimeUtoW(uint64_t ft); #ifndef _WIN32 uint64_t fileTimeUtoW( timespec const & ts ); #endif uint64_t fileTimeNow(); }