/* * Profiler.cpp * ------------ * Purpose: Performance measuring * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "Profiler.h" OPENMPT_NAMESPACE_BEGIN #ifdef USE_PROFILER class Statistics { public: Profile &profile; Profile::Data data; double usage; Statistics(Profile &p) : profile(p) { usage = 0.0; Update(); } void Update() { data = profile.GetAndResetData(); uint64 now = profile.GetTime(); uint64 timewindow = now - data.Start; if(data.Calls > 0 && timewindow > 0) { usage = (double)data.Sum / (double)timewindow; } else { usage = 0.0; } } }; struct ProfileBlock { class Profile * profile; const char * name; class Statistics * stats; }; static const std::size_t MAX_PROFILES = 1024; static ProfileBlock Profiles[ MAX_PROFILES ]; static std::size_t NextProfile = 0; static void RegisterProfile(Profile *newprofile) { if(NextProfile < MAX_PROFILES) { Profiles[NextProfile].profile = newprofile; Profiles[NextProfile].stats = 0; NextProfile++; } } static void UnregisterProfile(Profile *oldprofile) { for(std::size_t i=0; iUpdate(); } } } std::string Profiler::DumpProfiles() { std::string ret; for(std::size_t i=0; i Profiler::DumpCategories() { std::vector ret; ret.resize(Profiler::CategoriesCount); for(std::size_t i=0; iCategory] += Profiles[i].stats->usage; } } return ret; } uint64 Profile::GetTime() const { LARGE_INTEGER ret; ret.QuadPart = 0; QueryPerformanceCounter(&ret); return ret.QuadPart; } uint64 Profile::GetFrequency() const { LARGE_INTEGER ret; ret.QuadPart = 0; QueryPerformanceFrequency(&ret); return ret.QuadPart; } Profile::Profile(Profiler::Category category, const char *name) : Category(category), Name(name) { data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); EnterTime = 0; RegisterProfile(this); } Profile::~Profile() { UnregisterProfile(this); } Profile::Data Profile::GetAndResetData() { Profile::Data ret; datamutex.lock(); ret = data; data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); datamutex.unlock(); return ret; } void Profile::Reset() { datamutex.lock(); data.Calls = 0; data.Sum = 0; data.Overhead = 0; data.Start = GetTime(); datamutex.unlock(); } void Profile::Enter() { EnterTime = GetTime(); } void Profile::Leave() { uint64 LeaveTime = GetTime(); datamutex.lock(); data.Calls += 1; data.Sum += LeaveTime - EnterTime; datamutex.unlock(); } #else // !USE_PROFILER MPT_MSVC_WORKAROUND_LNK4221(Profiler) #endif // USE_PROFILER OPENMPT_NAMESPACE_END