I have been investigating thread priorities in Genode 26.05 on x86_64 with the NOVA microhypervisor. I would like to share my findings and get feedback on how priorities should be managed in a Genode-based system, particularly to prevent starvation and support time-sensitive workloads such as audio and video playback.
As part of this investigation, I implemented a PriorityThread abstraction that allows a thread’s priority to be specified when it is created. I then traced the priority values through Genode’s NOVA backend to verify that they reach the underlying scheduling contexts. My tests confirmed that the priority values are propagated to NOVA and that changing a thread’s priority affects its execution behavior in a CPU-bound workload.
For example, I tested three workers with different Genode priorities:
-
Worker 0: priority 0
-
Worker 1: priority 2000
-
Worker 2: priority 4000
In this configuration, lower Genode priority values correspond to higher priorities. The observed mapping to NOVA priorities was 64, 63, and 61, respectively.
In a continuous CPU-bound test, the highest-priority worker completed multiple work units during a 10-second observation interval, while the two lower-priority workers completed none.
This result appears consistent with the priority-based scheduling policy described in the NOVA documentation. I would like to make sure I understand this behavior correctly and have not overlooked anything.
Is assigning priorities to individual threads an appropriate way to control execution in Genode, or is the preferred approach based on other mechanisms, such as CPU-session configuration, resource quotas, scheduling contexts, or component architecture?
More specifically:
-
How should priorities be assigned to threads belonging to different components?
-
Is starvation an expected consequence of strict priority-based scheduling with NOVA, and should applications be designed with this behavior in mind?
-
Are there established ways to ensure that lower-priority threads still receive sufficient CPU time?
-
How should priorities and CPU resources be managed across components to prevent a single component from monopolizing CPU resources?
The Main Concern: Real-Time and Multimedia Workloads
My primary concern is the reliable execution of time-sensitive services, particularly audio and video playback, in a Genode-based system.
For example, video playback involves several activities that must make progress within appropriate time limits:
-
Video decoding
-
Audio decoding and playback
-
Display composition and rendering
-
Graphics and display driver activity
-
Storage and network I/O
-
Other system services running in the background
If CPU-bound work in one component prevents another activity from running on time, the result may be audio dropouts, video stuttering, or degraded playback quality.
What is the recommended approach to prioritizing these activities in Genode?
For example:
-
Should audio processing and playback receive higher scheduling priorities than video decoding and background tasks?
-
How should priorities be assigned to drivers and services that support time-sensitive workloads?
-
Are there recommended mechanisms to ensure that audio processing meets its deadlines without starving other components?
-
Does Genode provide an established approach for coordinating scheduling priorities across component boundaries?
-
Are there existing examples or configurations that demonstrate how to configure a system for smooth audio and video playback?
I understand that scheduling priorities alone cannot guarantee real-time behavior. I would also like to understand how CPU allocation, execution budgets, interrupt handling, and multimedia component architecture should be considered together.
Finally, do you consider explicit per-thread priority control a useful addition to Genode, or would you recommend a different approach to this problem?
If per-thread priorities are useful, what policy would you recommend for managing them across components while maintaining responsiveness for time-sensitive workloads and preventing starvation?
Any pointers to relevant documentation, existing implementations, or practical examples would be greatly appreciated.
Thank you for your time and feedback.