Determinism in Real Time Systems Explained

Mars Rover
CATEGORY

Real Time Systems

TAGS

Determinism, Priority Inversion, Real time systems

I used to think real-time systems were about speed. Raw throughput. The fastest possible response. If you had asked twenty-year-old me what a “real-time system” was, I would have described something like a race car. Faster equals better equals real-time. Simple, right?

Then I sat in a Real-Time Systems class at the University of Rostock, taught by Dr.-Ing. Michael Rethfeldt, and that whole mental model quietly fell apart.

The rover that crashed because of a stopwatch, not a rock

Dr. Michael opened with a story about NASA’s Mars Pathfinder rover. Not a story about broken hardware or a boulder in the way. A story about timing.

Here is roughly what happened. The rover ran a real-time operating system with tasks of different priorities. A low-priority task was responsible for collecting meteorological data, and it needed to briefly lock a shared resource to do its job. A high-priority task, responsible for managing the data bus, occasionally needed that same resource.

Normally this is fine. The high-priority task waits a moment for the low-priority task to finish, then goes about its very important business. But every so often, a medium-priority task would sneak in and hog the CPU while the low-priority task was still holding that shared resource. The high-priority task ended up waiting far longer than it should have, a watchdog timer noticed the system had gone quiet for too long, and the whole rover reset itself.

This is called priority inversion, and it is exactly what it sounds like: your priorities get inverted. The task that matters most ends up waiting on the task that matters least, because a task in the middle got in the way. NASA fixed it remotely by enabling something called priority inheritance, where a low-priority task temporarily borrows the priority of whatever high-priority task is waiting on it, so nothing sneaky can cut in line anymore.

Nobody wrote bad code here. Every individual piece of logic was correct. What failed was the assumption that timing would just work itself out. It did not. And a machine on Mars found that out the hard way, which is a genuinely expensive way to learn a lesson about scheduling.

So what does determinism actually mean

Here is the plain version. Determinism means a system meets its deadline every single time, under every condition, with zero exceptions. Not usually. Not on a good day. Every time.

Compare that to what most people picture when they hear “real-time,” which is closer to average speed. A system that responds in 2 milliseconds on average sounds fast. But if it occasionally spikes to 500 milliseconds under heavy load, and that spike happens at the exact wrong moment, you do not have a fast system. You have an unreliable one wearing a fast costume.

Think about a pacemaker. It does not need to send an electrical signal to your heart at record speed. It needs to send that signal at exactly the right moment, every single beat, for the rest of your life, without a single missed cycle. A pacemaker that works correctly 99.9 percent of the time is not an impressive piece of engineering. It is a device that will eventually kill someone. The same logic applies to the braking system in a self-driving car deciding whether to stop for a pedestrian. Average performance means nothing. Worst-case performance is the entire game.

How engineers actually check for this: worst-case execution time

This is where worst-case execution time analysis, or WCET, comes in. It sounds intimidating, so let me make it boring in a good way.

WCET is basically engineers asking: what is the absolute longest this piece of code could take to run, assuming everything that could go wrong on the hardware does go wrong at once. Cache misses. Pipeline stalls. Interrupts firing at the worst possible instant. WCET analysis assumes the universe is actively trying to slow your code down, and calculates the deadline math from that pessimistic worst case, not from a friendly average.

There are two broad ways to do this. Static analysis looks at the code and the hardware architecture mathematically, without running anything, and derives an upper bound. Measurement-based analysis actually runs the code thousands of times under different conditions and takes the worst observed time, then adds a safety margin on top because you can never be fully sure you triggered the actual worst case.

Once you have that number, task scheduling becomes an exercise in proving that even in the worst possible combination of circumstances, every task still meets its deadline. This is genuinely difficult, and genuinely why real-time systems engineers get paid to worry about things the rest of us never think about.

How engineers actually check for this: worst-case execution time

This is where worst-case execution time analysis, or WCET, comes in. It sounds intimidating, so let me make it boring in a good way.

WCET is basically engineers asking: what is the absolute longest this piece of code could take to run, assuming everything that could go wrong on the hardware does go wrong at once. Cache misses. Pipeline stalls. Interrupts firing at the worst possible instant. WCET analysis assumes the universe is actively trying to slow your code down, and calculates the deadline math from that pessimistic worst case, not from a friendly average.

There are two broad ways to do this. Static analysis looks at the code and the hardware architecture mathematically, without running anything, and derives an upper bound. Measurement-based analysis actually runs the code thousands of times under different conditions and takes the worst observed time, then adds a safety margin on top because you can never be fully sure you triggered the actual worst case.

Once you have that number, task scheduling becomes an exercise in proving that even in the worst possible combination of circumstances, every task still meets its deadline. This is genuinely difficult, and genuinely why real-time systems engineers get paid to worry about things the rest of us never think about.

Hard, soft, and firm: not all deadlines are equally dramatic

Not every real-time system needs the pacemaker level of paranoia, which is a relief, because otherwise nobody would ever ship anything.

A hard real-time system is one where missing a deadline is a total system failure. The pacemaker. An airbag deployment. Braking on a self-driving car. There is no partial credit here. Miss the deadline once and something breaks or someone gets hurt.

A soft real-time system is one where missing a deadline degrades quality but the system keeps limping along. Video streaming is the classic example. If a frame arrives a little late, you get a stutter or a dropped frame. Annoying, not catastrophic.

A firm real-time system sits in between. Missing the deadline makes that specific result useless, but it does not break the whole system. A stock trading algorithm that misses its execution window is a good example. The trade is now pointless, the opportunity is gone, but the trading system itself is still fine and moves on to the next opportunity.

Knowing which category you are actually building for changes everything about how paranoid your engineering needs to be.

What this looks like in code

Here is a simplified sketch of how a scheduler might reason about deadlines, just pseudocode, to make this concrete rather than abstract:

for each task in scheduled_tasks:
if task.remaining_time_until_deadline <= task.worst_case_execution_time:
run(task) # this task is now urgent, it must run
else:
queue(task) # this task can safely wait

if task.deadline_missed():
trigger_safety_response() # hard real-time system: this is not optional 

Notice the logic is not “run whichever task feels most important right now.” It is a constant, unforgiving comparison between how much time is left and how much time the worst case actually needs. That comparison, running continuously and correctly, is what determinism looks like in practice.

The takeaway

Real-time is not a compliment about speed. It is a promise about certainty. And the systems that matter most in the world, the ones keeping hearts beating and cars from hitting pedestrians, are not impressive because they are fast. They are impressive because they never, ever break that promise.

If you found this useful, I originally wrote a shorter version of this on LinkedIn. Come say hello there, I would genuinely like to hear what concept once completely rewired your thinking the way this one rewired mine.

Sources

  • NASA Jet Propulsion Laboratory, retrospective accounts of the Mars Pathfinder priority inversion incident (1997)
  • Liu, C. L. and Layland, J. W., “Scheduling Algorithms for Multiprogramming in a Hard-Real-Time Environment,” Journal of the ACM, 1973
  • General real-time systems coursework, Universität Rostock, Real-Time Systems (Dr.-Ing. Michael Rethfeldt)
Share this article

About the author

Mr Olubayo Samuel is an electrical engineer and researcher at Universität Rostock, a CTO, and a mentor to 600+ young technologists. He writes about engineering, faith, business, and building a life across two continents.

More Posts from me

Olubayo Samuel
6 September

If you have ever tapped your phone to pay for coffee and then walked past…

Olubayo Samuel
3 September

Working with AI Is Just Leadership in Disguise I have two certificates from Anthropic’s Claude…