Hello,
I run into an issue on Monterey (12.7.5). I have a bundled XPC service in my application which is displaying some stuff and playin sounds via NSSound.
I had a problem with playback due to service priority, so I use the trick with a reply block where I send a reply block to the service and basically just retain it and never call it.
This worked fine so far, but we have users, predominantly on Monterey, who are having a problem with sound playback. It's choppy and distorted when their machine is under load (where "load" often just means playing a video on YouTube in Chrome).
Is there anything else I can do to get the proper priority for my xpc service so I can avoid distorted sound?
Additionally the service type is Application and RunLoopType is NSRunLoop with JoinExistingSession set to true. The QoS level of main queue is 0x21 (user interactive) and I'm calling all the NSSound APIs on main queue.
I run into an issue on Monterey (12.7.5).
Are you seeing this issue on later system versions? This area of the system has been under very active development, so it's entirely possible for you app to be doing "the right thing" and simply not work correctly on the older system because the scheduler isn't working "right".
I have a bundled XPC service in my application which is displaying some stuff and playin sounds via NSSound.
Is your XPC service directly presenting it's own window(s) or is this coming through your main app? Also, being precise, is this a true XPC service (meaning it was directly launched by the parent app as a helper service) or this a standalone component (for example, a login item) that communicates using XPC?
Jumping to your message:
HALC_ProxyIOContext::IOWorkLoop: skipping cycle due to overload ... HALS_OverloadMessage: Overload due to client running as an adaptive unboosted
So indeed it seems to be some priority problem?
Sort of, though the term "priority" can be misleading. The standard Unix model is built around the idea that proceses are assigned a relatively fixed priority which is then use to schedule execution time, but macOS never really used that model (even in 10.0) and it's "modern" evolution has only widened that gap.
In terms of the message here, the audio system heavily relies on mach real time thread scheduling. Note that this is an example of how the standard "Unix priority" model doesn't really "fit" how macOS works. Real time threads are basically scheduled in terms of a specific amount of runtime during a particular time interval. They're designed to provide predictable execution time with low latency, not to provide substansial "overall" time.
In any case, the first message happens anytime the HAL realizes it hasn't gotten the execution time it expected, which will cause audio glitches. The second message is a diagnostic message about "why" that's occurred. In this case, "adaptive unboosted" means that it's running in a process where it's priority was so low that it real time thread was not scheduled.
That leads to here:
I had a problem with playback due to service priority, so I use the trick with a reply block where I send a reply block to the service and basically just retain it and never call it.
Part of what XPC "does" is transfer priority between threads/processes, so a high priority process (like an interactive app) doesn't get stuck waiting on a low priority daemon. Holding on to a reply like this means that the system views your process views your service as blocking the main app, which should elevate your processes priority.
A few things you should look at here:
-
What is your main app doing when the glitches actually happen? If it's been moved to the background, then the issue may actually be that your main app isn't actually "foreground interactive". If you're not already doing so, you may want to try having your app using "beginActivityWithOptions" to ensure that it's remaining active.
-
What are the XPC interactions between your app and service? Do you ever "reset" your held reply block, or are you just holding a single reply "forever"? Particularly on a old system like this, you may find that periodically "resetting" the message (say, every minute) works better than simply holding the same message "forever".
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware