51 workgroup_ = workgroup;
59 if (joined_)
return true;
63 int result = os_workgroup_join(workgroup_, &token_);
72 joined_ = capture_and_set_realtime_priority();
89 os_workgroup_leave(workgroup_, &token_);
90 }
else if (priority_thread_ != MACH_PORT_NULL) {
92 previous_constraint_is_default_
93 ? thread_policy_set(priority_thread_, THREAD_EXTENDED_POLICY,
94 reinterpret_cast<thread_policy_t
>(&previous_extended_),
95 THREAD_EXTENDED_POLICY_COUNT)
96 : thread_policy_set(priority_thread_, THREAD_TIME_CONSTRAINT_POLICY,
97 reinterpret_cast<thread_policy_t
>(&previous_constraint_),
98 THREAD_TIME_CONSTRAINT_POLICY_COUNT);
99 if (result != KERN_SUCCESS)
101 mach_port_deallocate(mach_task_self(), priority_thread_);
102 priority_thread_ = MACH_PORT_NULL;
115#if defined(__APPLE__)
120 thread_time_constraint_policy_data_t policy;
121 policy.period =
static_cast<uint32_t
>(5000000ULL *
timebase.denom /
timebase.numer);
122 policy.computation =
static_cast<uint32_t
>(3000000ULL *
timebase.denom /
timebase.numer);
123 policy.constraint =
static_cast<uint32_t
>(5000000ULL *
timebase.denom /
timebase.numer);
124 policy.preemptible = TRUE;
126 const auto thread = mach_thread_self();
127 kern_return_t result = thread_policy_set(thread, THREAD_TIME_CONSTRAINT_POLICY,
128 reinterpret_cast<thread_policy_t
>(&policy),
129 THREAD_TIME_CONSTRAINT_POLICY_COUNT);
131 mach_port_deallocate(mach_task_self(), thread);
132 return result == KERN_SUCCESS;
140#if defined(__APPLE__)
141 auto result = pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
143#elif defined(__linux__)
144 struct sched_param param;
145 param.sched_priority = sched_get_priority_max(SCHED_FIFO);
147 int policy = SCHED_OTHER;
148 param.sched_priority = 0;
149 pthread_setschedparam(pthread_self(), policy, ¶m);
160 bool joined_ =
false;
162#if defined(__APPLE__)
163 bool capture_and_set_realtime_priority() {
164 priority_thread_ = mach_thread_self();
165 auto count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
166 previous_constraint_is_default_ = FALSE;
167 auto result = thread_policy_get(priority_thread_, THREAD_TIME_CONSTRAINT_POLICY,
168 reinterpret_cast<thread_policy_t
>(&previous_constraint_),
169 &count, &previous_constraint_is_default_);
170 if (result == KERN_SUCCESS && previous_constraint_is_default_) {
171 count = THREAD_EXTENDED_POLICY_COUNT;
172 boolean_t get_default = FALSE;
173 result = thread_policy_get(priority_thread_, THREAD_EXTENDED_POLICY,
174 reinterpret_cast<thread_policy_t
>(&previous_extended_),
175 &count, &get_default);
179 mach_port_deallocate(mach_task_self(), priority_thread_);
180 priority_thread_ = MACH_PORT_NULL;
186 thread_t priority_thread_ = MACH_PORT_NULL;
187 thread_time_constraint_policy_data_t previous_constraint_{};
188 thread_extended_policy_data_t previous_extended_{};
189 boolean_t previous_constraint_is_default_ = FALSE;
190 os_workgroup_t workgroup_ =
nullptr;
191 os_workgroup_join_token_s token_{};