From 32cef906b02562ffb129b095386a9314abde82f1 Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 3 Jan 2022 11:26:23 +0100 Subject: Core/Time: Remove artificially high minimal update intervals (cherry picked from commit 3a67e376811743be208da4aab8a9e452e1ae637e) --- src/server/worldserver/Main.cpp | 55 +++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'src/server/worldserver/Main.cpp') diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 418b5de5eb1..888b0ad65d4 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -67,7 +67,7 @@ namespace fs = boost::filesystem; #define _TRINITY_CORE_CONFIG "worldserver.conf" #endif -#define WORLD_SLEEP_CONST 50 +#define WORLD_SLEEP_CONST 1 #ifdef _WIN32 #include "ServiceWin32.h" @@ -81,6 +81,9 @@ char serviceDescription[] = "TrinityCore World of Warcraft emulator world servic * 2 - paused */ int m_ServiceStatus = -1; + +#include +#include #endif class FreezeDetector @@ -135,6 +138,44 @@ extern int main(int argc, char** argv) return WinServiceUninstall() == true ? 0 : 1; else if (configService.compare("run") == 0) WinServiceRun(); + + Optional newTimerResolution; + boost::system::error_code dllError; + std::shared_ptr winmm(new boost::dll::shared_library("winmm.dll", dllError, boost::dll::load_mode::search_system_folders), [&](boost::dll::shared_library* lib) + { + try + { + if (newTimerResolution) + lib->get("timeEndPeriod")(*newTimerResolution); + } + catch (std::exception const&) + { + // ignore + } + + delete lib; + }); + + if (winmm->is_loaded()) + { + try + { + auto timeGetDevCapsPtr = winmm->get("timeGetDevCaps"); + // setup timer resolution + TIMECAPS timeResolutionLimits; + if (timeGetDevCapsPtr(&timeResolutionLimits, sizeof(TIMECAPS)) == TIMERR_NOERROR) + { + auto timeBeginPeriodPtr = winmm->get("timeBeginPeriod"); + newTimerResolution = std::min(std::max(timeResolutionLimits.wPeriodMin, 1u), timeResolutionLimits.wPeriodMax); + timeBeginPeriodPtr(*newTimerResolution); + } + } + catch (std::exception const& e) + { + printf("Failed to initialize timer resolution: %s\n", e.what()); + } + } + #endif std::string configError; @@ -445,16 +486,16 @@ void WorldUpdateLoop() realCurrTime = getMSTime(); uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime); + if (!diff) + { + // sleep until enough time passes that we can update all timers + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } sWorld->Update(diff); realPrevTime = realCurrTime; - uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime()); - - // we know exactly how long it took to update the world, if the update took less than WORLD_SLEEP_CONST, sleep for WORLD_SLEEP_CONST - world update time - if (executionTimeDiff < WORLD_SLEEP_CONST) - std::this_thread::sleep_for(std::chrono::milliseconds(WORLD_SLEEP_CONST - executionTimeDiff)); - #ifdef _WIN32 if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); -- cgit v1.2.3