From dab22a7c70bdbba9c3d79d39a94d8a5681c10792 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 30 Sep 2024 19:57:53 +0200 Subject: [PATCH] Explicitly set Windows Process Scheduling Class --- libs/pbd/pthread_utils.cc | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index ef562a0495..94cdc1da41 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -23,6 +23,10 @@ #include #include +#ifdef PLATFORM_WINDOWS +#include +#endif + #if !defined PLATFORM_WINDOWS && defined __GLIBC__ #include #include @@ -55,6 +59,49 @@ static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIAL static Glib::Threads::Private thread_name (free); static int base_priority_relative_to_max = -20; +#ifdef PLATFORM_WINDOWS +static +std::string GetLastErrorAsString() +{ + DWORD err = ::GetLastError(); + if(err == 0) { + return std::string (); + } + + LPSTR buf = nullptr; + size_t size = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL); + + std::string rv (buf, size); + LocalFree (buf); + return rv; +} + +static bool +set_win_set_realtime_policy (pthread_t thread, int priority) +{ + if (priority < 12) { + return false; + } + bool ok = false; + + if (SetPriorityClass (GetCurrentProcess (), 0x00000100 /* REALTIME_PRIORITY_CLASS */)) { + /* see https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities */ + ok = SetThreadPriority (pthread_gethandle (thread), priority); + DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Using Windows RT thread class. set priority: %1\n", ok ? "OK" : GetLastErrorAsString ())); + } else { + DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Cannot use Windows RT thread class: %1\n", GetLastErrorAsString ())); + ok = SetPriorityClass (GetCurrentProcess (), 0x00000080 /* HIGH_PRIORITY_CLASS */); + DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Using Windows high priority thread class: %1\n", ok ? "OK" : GetLastErrorAsString ())); + if (ok) { + ok = SetThreadPriority (pthread_gethandle (thread), priority); + DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Set Windows high thread priority: %1\n", ok ? "OK" : GetLastErrorAsString ())); + } + } + return ok; +} +#endif + namespace PBD { PBD::Signal3 ThreadCreatedWithRequestSize; @@ -370,6 +417,12 @@ pbd_realtime_pthread_create ( DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Start Realtime Thread policy = %1 priority = %2 stacksize = 0x%3%4\n", policy, parm.sched_priority, std::hex, stacksize)); rv = pthread_create (thread, &attr, start_routine, arg); pthread_attr_destroy (&attr); + +#ifdef PLATFORM_WINDOWS + if (0 == rv && thread && parm.sched_priority >= 12) { + set_win_set_realtime_policy (*thread, parm.sched_priority); + } +#endif return rv; } @@ -386,6 +439,14 @@ pbd_set_thread_priority (pthread_t thread, int policy, int priority) DEBUG_TRACE (PBD::DEBUG::Threads, string_compose ("Change '%1' to policy = %2 priority = %3\n", pthread_name(), policy, param.sched_priority)); +#ifdef PLATFORM_WINDOWS + if (thread && param.sched_priority >= 12) { + if (set_win_set_realtime_policy (thread, param.sched_priority)) { + return 0; + } + } +#endif + return pthread_setschedparam (thread, SCHED_FIFO, ¶m); }