[Audio Threads] Set realtime priority on old OS
Set baseline real-time priority for audio threads even on old macOS, since that API is available there. Only set it once, and do not attempt again if it fails, only once per thread. Signed-off-by: Christopher Snowhill <kode54@gmail.com>swiftingly
parent
7813712df3
commit
6bd0bf1dc5
|
@ -29,6 +29,7 @@
|
|||
BOOL shouldContinue;
|
||||
BOOL endOfStream; // All data is now in buffer
|
||||
BOOL initialBufferFilled;
|
||||
BOOL isRealtime, isRealtimeError; // If was successfully set realtime, or if error
|
||||
|
||||
AudioStreamBasicDescription nodeFormat;
|
||||
uint32_t nodeChannelConfig;
|
||||
|
|
|
@ -31,7 +31,7 @@ static const os_clockid_t clockId = OS_CLOCK_MACH_ABSOLUTE_TIME;
|
|||
|
||||
// Enables time-contraint policy and priority suitable for low-latency,
|
||||
// glitch-resistant audio.
|
||||
void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
||||
BOOL SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
||||
kern_return_t result;
|
||||
|
||||
// Increase thread priority to real-time.
|
||||
|
@ -50,7 +50,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
THREAD_EXTENDED_POLICY_COUNT);
|
||||
if(result != KERN_SUCCESS) {
|
||||
DLog(@"thread_policy_set extended policy failure: %d", result);
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Set to relatively high priority.
|
||||
|
@ -62,7 +62,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
THREAD_PRECEDENCE_POLICY_COUNT);
|
||||
if(result != KERN_SUCCESS) {
|
||||
DLog(@"thread_policy_set precedence policy failure: %d", result);
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Most important, set real-time constraints.
|
||||
|
@ -106,7 +106,10 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
if(result != KERN_SUCCESS) {
|
||||
DLog(@"thread_policy_set constraint policy failure: %d", result);
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@implementation Node
|
||||
|
@ -213,10 +216,11 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
if(!wg) {
|
||||
if(!workgroup) {
|
||||
workgroup = AudioWorkIntervalCreate([[NSString stringWithFormat:@"%@ Work Interval", [self className]] UTF8String], clockId, &attr);
|
||||
SetPriorityRealtimeAudio(pthread_mach_thread_np(pthread_self()));
|
||||
isRealtimeError = !SetPriorityRealtimeAudio(pthread_mach_thread_np(pthread_self()));
|
||||
isRealtime = !isRealtimeError;
|
||||
}
|
||||
wg = workgroup;
|
||||
if(wg) {
|
||||
if(wg && !isRealtimeError) {
|
||||
int result = os_workgroup_join(wg, &wgToken);
|
||||
if(result == 0) return;
|
||||
if(result == EALREADY) {
|
||||
|
@ -226,12 +230,17 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(!isRealtime && !isRealtimeError) {
|
||||
isRealtimeError = SetPriorityRealtimeAudio(pthread_mach_thread_np(pthread_self()));
|
||||
isRealtime = !isRealtimeError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)leaveWorkgroup {
|
||||
if(@available(macOS 11, *)) {
|
||||
if(wg) {
|
||||
if(wg && !isRealtimeError) {
|
||||
os_workgroup_leave(wg, &wgToken);
|
||||
wg = nil;
|
||||
}
|
||||
|
@ -240,7 +249,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
|
||||
- (void)startWorkslice {
|
||||
if(@available(macOS 11, *)) {
|
||||
if(wg) {
|
||||
if(wg && !isRealtimeError) {
|
||||
const uint64_t currentTime = mach_absolute_time();
|
||||
const uint64_t deadline = currentTime + intervalMachLength;
|
||||
int result = os_workgroup_interval_start(wg, currentTime, deadline, nil);
|
||||
|
@ -253,7 +262,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
|
|||
|
||||
- (void)endWorkslice {
|
||||
if(@available(macOS 11, *)) {
|
||||
if(wg) {
|
||||
if(wg && !isRealtimeError) {
|
||||
int result = os_workgroup_interval_finish(wg, nil);
|
||||
if(result != 0) {
|
||||
DLog(@"Deadline end error = %d", result);
|
||||
|
|
Loading…
Reference in New Issue