I agree with
@Nycturne here, and I think Apple *specifically* named the QoS classes using a naming scheme different than very low/low/medium/high/very high to nudge the people towards not using the QoS APIs like this. The classes are actually called background/utility/user initiated/user interactive. So the specific set of questions that you usually need to ask yourself as a developer looks like something more similar to:
- Are you building your own run loop, or a rendering application? ->
userInteractive
- Is the user actively waiting for this work to finish, blocked from performing further actions? ->
userInitiated
- Is the user waiting for this work to finish, but able to perform other actions in the meantime? ->
utility
- Is this work explicitly low priority, doesn't have a definite deadline, and should use as little power as possible? ->
background
This pretty much prevents the case described above from ever happening. If a task is so low priority that the user is not actively waiting for it, it must be either
utility
or
background
. Since we want to continuously process something, it has a definite deadline (no
background
) so we'll need to keep the task in
utility
. Then if that task can spawn more work, the user obviously must not be actively waiting for them to finish (I couldn't come up with an example of an app that randomly blocks the UI with a loading screen after an untracked background operation finishes), so the tasks probably would need to be executed as
utility
as well.
This doesn't mean that they won't be executed in the P cores, or that the system won't race to sleep. I'd argue that the most important responsibility of the scheduler is guaranteeing that in a contended system (more things running at once than the CPU can tackle at once) things the user is actively waiting on finish earlier than things the user isn't actively waiting on. If this app is the only thing you're running, and you're not in low power mode, chances are all these
utility
stuff would run in the P cores anyway (except the long-running job, which could get to a lower priority band through priority decay mechanisms).