On Wed Feb 19 06:30:08 2025 +0000, Brendan Shanks wrote:
For what it's worth, Apple includes a game sample with the Game Porting Toolkit that creates a high-priority render thread using `SCHED_RR` and `sched_priority = 45` (take a look at gptk-sample/08 - MetalRendering/README.md` in `Game_Porting_Toolkit_2.0.dmg`). I can also ask our Apple contact whether they'd recommend setting priorities into the realtime band.
The realtime band should only be used by audio and video applications mostly I believe (and currently wine does not implement completely independent per thread priorities from the process priority class anyways, that's something that will be in part 3 though), so it is more of an audio or video server/driver kind of usage. That is also where this API is being used on macOS, like in some VLC-demux plugins or Jack2.
IIRC on windows at least administrative privileges are needed to use the NT realtime bad, so it's not something games usually do. I tried to capture as much of the NT semantics as possible, including preemption with priority 31, as discussed [here](https://community.osr.com/t/thread-boost-and-dynamic-priority/58044/6) (I ignored the job object part intentionally for now though and I believe that is something that isn't fully implemented anyways atm):
As was mentioned your process will need REALTIME_PRIORITY_CLASS to reach priority 31 (or anything above 15). With a priority of 31, you can also receive “non-preemptive scheduling” from the dispatcher if you also create a job object for the process and set JobObjectBasicLimitInformation with a SchedulingClass of 9. Note that scheduling class is not the same as priority.
To get an effective scheduling priority on a thread of native priority 45, with this current implementation it could be a combination of `ABOVE_NORMAL_PRIORITY_CLASS` + `THREAD_PRIORITY_ABOVE_NORMAL`. Or alternatively with part 3 a normal `NORMAL_PRIORITY_CLASS` + `THREAD_PRIORITY_NORMAL` with a +3 boost (which is a fairly common value for the main thread on Windows), or anything else really that results in an NT base priority of 11.
This implementation differs from `SCHED_RR` in the way in that it brings back thread QoS classes, after setting thread importance, and I believe `SCHED_RR` is also setting `thread_extended_policy.timeshare` to 0, which is something this current implementation only does for `THREAD_PRIORITY_TIME_CRITICAL` and the realtime band.
But it would be interesting to hear the input of an Apple contact on this as well.