Determinism and Real-Time Systems
Determinism refers to a system consistently producing the same results for the same inputs and executing them within predictable time constraints. This concept is critically important in real-time systems, as producing correct results alone is insufficient—these results must also be delivered within specific time limits. The traditional Linux kernel is designed to optimize throughput and overall system performance. This approach ensures fair sharing of CPU time and achieves high efficiency across the system but does not guarantee deterministic behavior. The kernel itself is designed as non-preemptible, meaning that when a process is running in kernel mode, even a higher-priority process cannot interrupt it. This leads to unpredictable execution times for interrupt handlers and system calls.Preempt-RT
Preempt-RT is a patchset that adapts the Linux kernel for real-time applications. This patch makes nearly the entire kernel preemptible, allowing high-priority processes to interrupt lower-priority ones running in kernel mode. The primary goal of Preempt-RT is to minimize latency across the system and provide deterministic behavior guarantees for real-time processes. While this approach slightly reduces system throughput, it delivers the predictable performance required for time-critical applications. The Gemstone Minimal image uses the Preempt-RT Linux kernel by default.Example Application
Thepreempt-rt
project in the t3gemstone/examples repository is a benchmarking tool designed to test real-time task performance on the Linux Preempt-RT kernel. The program’s main purpose is to measure latency and jitter—critical metrics in real-time systems—to analyze system performance. The application simulates a task running at a 1-millisecond period, evaluating how consistently and predictably it executes.
The program works by first creating a real-time thread using the SCHED_FIFO
scheduling policy and assigning it a high priority (priority 80). This thread simulates a task that should run every 1ms, using the clock_nanosleep()
function for precise timing. Additionally, the program locks memory pages in RAM using mlockall()
to prevent page faults and reduce delays. Over 10,000 iterations, it collects performance data, measuring the difference between expected and actual wake-up times (latency) and the consistency of the period (jitter).