From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- .../openmpt-trunk/common/Profiler.cpp | 221 +++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 Src/external_dependencies/openmpt-trunk/common/Profiler.cpp (limited to 'Src/external_dependencies/openmpt-trunk/common/Profiler.cpp') diff --git a/Src/external_dependencies/openmpt-trunk/common/Profiler.cpp b/Src/external_dependencies/openmpt-trunk/common/Profiler.cpp new file mode 100644 index 00000000..c73dab88 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/common/Profiler.cpp @@ -0,0 +1,221 @@ +/* + * 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 constexpr 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 -- cgit