3#include <ossia/detail/sleep.hpp>
17 using set_characteristics_t = HANDLE(WINAPI*)(LPCWSTR, LPDWORD);
18 using set_priority_t = BOOL(WINAPI*)(HANDLE, AVRT_PRIORITY);
19 using revert_t = BOOL(WINAPI*)(HANDLE);
21 set_characteristics_t set_characteristics{};
22 set_priority_t set_priority{};
27 if(HMODULE lib = LoadLibraryW(L
"avrt.dll"))
29 set_characteristics =
reinterpret_cast<set_characteristics_t
>(
30 reinterpret_cast<void*
>(GetProcAddress(lib,
"AvSetMmThreadCharacteristicsW")));
31 set_priority =
reinterpret_cast<set_priority_t
>(
32 reinterpret_cast<void*
>(GetProcAddress(lib,
"AvSetMmThreadPriority")));
33 revert =
reinterpret_cast<revert_t
>(
34 reinterpret_cast<void*
>(GetProcAddress(lib,
"AvRevertMmThreadCharacteristics")));
39inline const mmcss_api& mmcss() noexcept
41 static const mmcss_api api;
47struct priority_boost_handle
50 explicit priority_boost_handle(
double frequencyHz)
57 const auto& mmcss = detail::mmcss();
58 if (mmcss.set_characteristics)
59 m_mmcss = mmcss.set_characteristics(L
"Pro Audio", &taskIndex);
60 if (m_mmcss && mmcss.set_priority)
62 mmcss.set_priority(m_mmcss, AVRT_PRIORITY_CRITICAL);
64#elif defined(__APPLE__)
67 mach_port_t threadPort = pthread_mach_thread_np(pthread_self());
70 double periodNs = 1'000'000'000.0 / frequencyHz;
71 uint32_t periodMach =
static_cast<uint32_t
>(periodNs * detail::g_timebase_info.denom / detail::g_timebase_info.numer);
73 thread_time_constraint_policy_data_t policy;
74 policy.period = periodMach;
75 policy.computation = periodMach / 10;
76 policy.constraint = periodMach / 2;
77 policy.preemptible = 1;
79 kern_return_t kr = thread_policy_set(
81 THREAD_TIME_CONSTRAINT_POLICY,
82 reinterpret_cast<thread_policy_t
>(&policy),
83 THREAD_TIME_CONSTRAINT_POLICY_COUNT
86 m_policy_set = (kr == KERN_SUCCESS);
91 pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
95 pthread_getschedparam(pthread_self(), &m_original_policy, &m_original_param);
98 struct sched_param param;
99 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
101 if (pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) == 0)
108 setpriority(PRIO_PROCESS, 0, -20);
113 ~priority_boost_handle()
118 if (
const auto& mmcss = detail::mmcss(); mmcss.revert)
119 mmcss.revert(m_mmcss);
122#elif defined(__APPLE__)
126 mach_port_t threadPort = pthread_mach_thread_np(pthread_self());
127 thread_standard_policy_data_t policy;
130 THREAD_STANDARD_POLICY,
131 reinterpret_cast<thread_policy_t
>(&policy),
132 THREAD_STANDARD_POLICY_COUNT
134 m_policy_set =
false;
139 pthread_setschedparam(pthread_self(), m_original_policy, &m_original_param);
147 HANDLE m_mmcss =
nullptr;
148 UINT m_timer_resolution = 1;
149#elif defined(__APPLE__)
150 bool m_policy_set =
false;
152 int m_original_policy = SCHED_OTHER;
153 struct sched_param m_original_param = {};
154 bool m_elevated =
false;