Cont'd work to improve macOS rt priority
This commit is contained in:
parent
e82b2b48fb
commit
438b1e5eab
@ -96,7 +96,7 @@ RTTaskList::reset_thread_list ()
|
||||
PBD::fatal << _("Cannot create thread for TaskList!") << " (" << strerror(rv) << ")" << endmsg;
|
||||
/* NOT REACHED */
|
||||
}
|
||||
pbd_mach_set_realtime_policy (thread_id, 5. * 1e-5);
|
||||
pbd_mach_set_realtime_policy (thread_id, 5. * 1e-5, false);
|
||||
_threads.push_back (thread_id);
|
||||
}
|
||||
}
|
||||
|
@ -339,10 +339,10 @@ CoreAudioBackend::set_buffer_size (uint32_t bs)
|
||||
}
|
||||
_pcmio->set_samples_per_period(bs);
|
||||
if (_run) {
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * bs / _samplerate);
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * bs / _samplerate, true);
|
||||
}
|
||||
for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i) {
|
||||
pbd_mach_set_realtime_policy (*i, 1e9 * bs / _samplerate);
|
||||
pbd_mach_set_realtime_policy (*i, 1e9 * bs / _samplerate, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -854,7 +854,7 @@ CoreAudioBackend::create_process_thread (boost::function<void()> func)
|
||||
PBD::warning << _("AudioEngine: process thread failed to acquire realtime permissions.") << endmsg;
|
||||
}
|
||||
|
||||
if (pbd_mach_set_realtime_policy (thread_id, 1e9 * _samples_per_period / _samplerate)) {
|
||||
if (pbd_mach_set_realtime_policy (thread_id, 1e9 * _samples_per_period / _samplerate, false)) {
|
||||
PBD::warning << _("AudioEngine: process thread failed to set mach realtime policy.") << endmsg;
|
||||
}
|
||||
|
||||
@ -1321,7 +1321,7 @@ CoreAudioBackend::freewheel_thread ()
|
||||
AudioEngine::thread_init_callback (this);
|
||||
_midiio->set_enabled(false);
|
||||
reset_midi_parsers ();
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * _samples_per_period / _samplerate);
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * _samples_per_period / _samplerate, true);
|
||||
}
|
||||
|
||||
// process port updates first in every cycle.
|
||||
@ -1388,7 +1388,7 @@ CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t hos
|
||||
_reinit_thread_callback = false;
|
||||
_main_thread = pthread_self();
|
||||
AudioEngine::thread_init_callback (this);
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * _samples_per_period / _samplerate);
|
||||
pbd_mach_set_realtime_policy (_main_thread, 1e9 * _samples_per_period / _samplerate, true);
|
||||
}
|
||||
|
||||
if (pthread_mutex_trylock (&_process_callback_mutex)) {
|
||||
|
@ -80,7 +80,7 @@ LIBPBD_API int pbd_realtime_pthread_create (
|
||||
|
||||
LIBPBD_API int pbd_absolute_rt_priority (int policy, int priority);
|
||||
LIBPBD_API int pbd_set_thread_priority (pthread_t, const int policy, int priority);
|
||||
LIBPBD_API bool pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns);
|
||||
LIBPBD_API bool pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns, bool main);
|
||||
|
||||
namespace PBD {
|
||||
LIBPBD_API extern void notify_event_loops_about_thread_creation (pthread_t, const std::string&, int requests = 256);
|
||||
|
@ -339,40 +339,75 @@ pbd_set_thread_priority (pthread_t thread, const int policy, int priority)
|
||||
}
|
||||
|
||||
bool
|
||||
pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns)
|
||||
pbd_mach_set_realtime_policy (pthread_t thread_id, double period_ns, bool main)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
/* https://opensource.apple.com/source/xnu/xnu-4570.61.1/osfmk/mach/thread_policy.h.auto.html
|
||||
* https://opensource.apple.com/source/xnu/xnu-4570.61.1/:sposfmk/kern/sched.h.auto.html
|
||||
*/
|
||||
kern_return_t res;
|
||||
|
||||
/* Ask for fixed priority */
|
||||
thread_extended_policy_data_t tep;
|
||||
tep.timeshare = false;
|
||||
|
||||
res = thread_policy_set (pthread_mach_thread_np (thread_id),
|
||||
THREAD_EXTENDED_POLICY,
|
||||
(thread_policy_t)&tep,
|
||||
THREAD_EXTENDED_POLICY_COUNT);
|
||||
#ifndef NDEBUG
|
||||
printf ("Mach Thread(%p) set timeshare: %d OK: %d\n", thread_id, tep.timeshare, res == KERN_SUCCESS);
|
||||
#endif
|
||||
|
||||
/* relative value of the computation compared to the other threads in the task. */
|
||||
thread_precedence_policy_data_t tpp;
|
||||
tpp.importance = main ? 63 : 62; // MAXPRI_USER = 63
|
||||
|
||||
res = thread_policy_set (pthread_mach_thread_np (thread_id),
|
||||
THREAD_PRECEDENCE_POLICY,
|
||||
(thread_policy_t)&tpp,
|
||||
THREAD_PRECEDENCE_POLICY_COUNT);
|
||||
#ifndef NDEBUG
|
||||
printf ("Mach Thread(%p) set precedence: %d OK: %d\n", thread_id, tpp.importance, res == KERN_SUCCESS);
|
||||
#endif
|
||||
|
||||
/* Realtime constraints */
|
||||
double ticks_per_ns = 1.;
|
||||
mach_timebase_info_data_t timebase;
|
||||
if (KERN_SUCCESS == mach_timebase_info (&timebase)) {
|
||||
ticks_per_ns = timebase.denom / timebase.numer;
|
||||
}
|
||||
|
||||
thread_time_constraint_policy_data_t policy;
|
||||
thread_time_constraint_policy_data_t tcp;
|
||||
#ifndef NDEBUG
|
||||
mach_msg_type_number_t msgt = 4;
|
||||
boolean_t dflt = false;
|
||||
kern_return_t rv = thread_policy_get (pthread_mach_thread_np (thread_id),
|
||||
THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&policy, &msgt, &dflt);
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t)&tcp,
|
||||
&msgt, &dflt);
|
||||
|
||||
printf ("Mach Thread(%p) get: period=%d comp=%d constraint=%d preemt=%d OK: %d\n", thread_id, policy.period, policy.computation, policy.constraint, policy.preemptible, rv == KERN_SUCCESS);
|
||||
printf ("Mach Thread(%p) get: period=%d comp=%d constraint=%d preemt=%d OK: %d\n", thread_id, tcp.period, tcp.computation, tcp.constraint, tcp.preemptible, rv == KERN_SUCCESS);
|
||||
#endif
|
||||
|
||||
mach_timebase_info_data_t timebase_info;
|
||||
mach_timebase_info (&timebase_info);
|
||||
const double period_clk = period_ns * (double)timebase_info.denom / (double)timebase_info.numer;
|
||||
|
||||
policy.period = ticks_per_ns * period_clk;
|
||||
policy.computation = ticks_per_ns * period_clk * .9;
|
||||
policy.constraint = ticks_per_ns * period_clk * .95;
|
||||
policy.preemptible = true;
|
||||
kern_return_t res = thread_policy_set (pthread_mach_thread_np (thread_id),
|
||||
THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&policy,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
tcp.period = ticks_per_ns * period_clk;
|
||||
tcp.computation = ticks_per_ns * period_clk * .9;
|
||||
tcp.constraint = ticks_per_ns * period_clk * .95;
|
||||
tcp.preemptible = true;
|
||||
|
||||
res = thread_policy_set (pthread_mach_thread_np (thread_id),
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t)&tcp,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
|
||||
#ifndef NDEBUG
|
||||
printf ("Mach Thread(%p) set: period=%d comp=%d constraint=%d preemt=%d OK: %d\n", thread_id, policy.period, policy.computation, policy.constraint, policy.preemptible, res == KERN_SUCCESS);
|
||||
printf ("Mach Thread(%p) set: period=%d comp=%d constraint=%d preemt=%d OK: %d\n", thread_id, tcp.period, tcp.computation, tcp.constraint, tcp.preemptible, res == KERN_SUCCESS);
|
||||
#endif
|
||||
|
||||
return res != KERN_SUCCESS;
|
||||
#endif
|
||||
return false; // OK
|
||||
|
Loading…
Reference in New Issue
Block a user