RK0 provides a fair amount of sleep primitives, each one tailored for a different concurrency demand.

kSleepDelay(t) — Sleep for at least t ticks
The Idea: It’s a straightforward time‑blocking primitive. The task voluntarily gives up the processor and tells the kernel: “Take me out of the RUNNING state and put me in SLEEPING for at least t ticks from now.”
It’s entirely susceptible to code execution time and preemption. The current call does not mind about how long the task actually has slept. So, it is not useful for periodic tasks.
kSleepRelease(period) — Global Phase-Locked Alignment
The Idea: Designed for strictly periodic tasks. Instead of looking at the current clock, the kernel calculates the elapsed time since the ideal moment when the task should have been released (Release Time).
If a task with a 300‑tick period is delayed due to long processing and only manages to call the primitive 320 ticks later, RK0 detects the +20‑tick error. In the next cycle, the kernel shortens the sleep time to 280 ticks. On the other hand, if the error is higher or equal to a +300-tick error, the kernel skips that call, so the next call happens on the next multiple of 300.
Practical Example (PID Control Algorithm / Frequency Inverter): Essential for closed‑loop control systems that calculate mathematical derivatives or integrals. If you sample a motor’s speed every 10 ms, the phase with the master clock cannot drift at all, or the mathematical error calculation diverges and the motor oscillates destructively. kSleepRelease guarantees full phase alignment.
kSleepUntil(&anchor, period) — Local Period Protected Against Avalanche
The Idea: Similar to the compensation mechanism, but instead of relying on the kernel’s global phase, it uses a local reference variable (anchor) controlled by the task itself.
The critical differentiator of kSleepUntil appears when there is a catastrophic CPU delay (longer than the task’s own period). In common kernels, when the delay passes, the operating system runs the task several times in a row in a “storm” to try to catch up the accumulated backlog. RK0’s kSleepUntil is smart: if the delay is huge, it gives up on making up for the accumulated backlog in the past, updates the anchor to the current time, and forces the task to run immediately only once, preventing a CPU overload avalanche collapse.
Practical Example (Industrial SPI Sensor Reading): You read a sensor every 5 ms. If the system suffers a massive 15‑ms preemption due to a critical network interrupt, the task misses 3 sampling cycles. When it finally regains the CPU, you do not want the chip to read the sensor 3 times in a row instantly (which would produce repeated, useless data). kSleepUntil makes the task process the sensor once now and realigns the next 5‑ms cycles from this new point.
kBusyDelay(t) (Decrement only while RUNNING)
The Idea: Useful and simple. It does not put the task to sleep; it makes the task keep consuming CPU time in busy‑wait mode for t ticks. Say want to emulate a workload as a stub, stress test. To properly emulating a work that take a given time, it means that the countdown should happen iff RUNNING, the very opposite of kSleep.
Practical Example: stressing the workload of a task to see how it affects the overall real‑ttime responsiveness, helping to assign an optimal priority.

Leave a Reply