Class Realtime
- Direct Known Subclasses:
BoardRealtime
Entry point to real-time threads: periodic tasks that run at a fixed operating-system priority, are released on an absolute clock, and are not paused by the garbage collector.
Realtime rt = Realtime.getInstance();
rt.lockMemory(); // no page faults in a period
rt.setMemoryLimit(64L * 1024 * 1024); // fail fast instead of thrashing
RealtimeThread motor = rt.start("motor",
new RealtimeParameters().setPeriodNanos(1000000L).setPriority(80).setCpu(3),
new MotorLoop());
...
Log.p(motor.getStatistics().toString());
How the collector is kept away
A real-time task allocates in setup() and never in cycle(). The build rejects an
allocation that cycle() reaches, and at run time an allocation it could not see
ends the steady state with a RealtimeAllocationError -- so the thread never needs
the collector to make room. The collector in turn never stops it for a whole cycle:
collections stay concurrent while a real-time thread exists, its stack is scanned
while it sleeps between periods, and it is released as soon as that one stack has
been read. Normal threads run below it, the collector's included, so a busy
collector slows them, not it.
What this is and is not
On Linux with a PREEMPT_RT kernel this is firm real time: release latency in tens
of microseconds, measured, not proven. It is not certified hard real time and makes
no claim under any safety standard. Measure the loop on the device, under load,
with RealtimeThread.getStatistics().
Platforms
- Linux (the embedded and desktop Linux targets, the backend on Linux): every
feature. Real-time scheduling needs
CAP_SYS_NICEor anrtpriolimit. - Other translated targets (iOS, macOS, Windows, the backend elsewhere): the collector isolation and the allocation check, with normal-priority threads and a relative sleep.
- The simulator, Android, JavaScript: a best-effort Java thread with the same API, so the application runs and can be tested anywhere; there is no isolation from the collector and no allocation check at run time.
For port implementors
A port subclasses this class and overrides the protected primitives, which act on the calling thread. The defaults are the best-effort Java implementation.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected static final intrawEnter(RealtimeThread, int, int, boolean)result bit: CPU pinned.protected static final intrawEnter(RealtimeThread, int, int, boolean)result bit: other threads moved off.protected static final intrawEnter(RealtimeThread, int, int, boolean)result bit: scheduling applied.static final intAllocation in a cycle is detected at run time.static final intThreads can be pinned to a CPU.static final intReal-time threads are not paused by the garbage collector.static final intLocking the process's memory so it is never paged out (lockMemory()).static final intThe kernel is aPREEMPT_RTkernel, which bounds its own latency.static final intReal-time scheduling (SCHED_FIFOon Linux). -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedRealtime()Ports construct subclasses; applications callgetInstance(). -
Method Summary
Modifier and TypeMethodDescriptionstatic RealtimeReturns the real-time entry point of the current platform.protected intBit mask of theFEATURE_constants this platform provides.static voidbooleanisSupported(int feature) truewhen the platform provides the feature, one of theFEATURE_constants.booleanLocks every page the process has and will have into memory, so a period never waits for one to be paged in.protected intrawEnter(RealtimeThread thread, int priority, int cpu, boolean isolate) Makes the calling thread real-time.protected voidrawFreeze(RealtimeThread thread, int budget, RealtimeAllocationError error) Enters the steady state on the calling thread: from here an allocation beyondbudgetper period throwserror.protected StringrawLastViolation(RealtimeThread thread) The class of the allocation that ended the calling thread's last steady state, ornull.protected voidrawLeave(RealtimeThread thread) Returns the calling thread to normal scheduling.protected intLocks the process's memory.protected voidrawSetMemoryLimit(long bytes, OutOfMemoryError error) Installs the memory limit;erroris the instance to throw.protected voidrawStartPeriod(RealtimeThread thread, long periodNanos) Starts the periodic clock on the calling thread; the first release is one period from now.protected voidrawStatistics(RealtimeThread thread, long[] out) Copies the calling thread's statistics intoout(RealtimeStatistics.COUNTvalues).protected voidrawThaw(RealtimeThread thread) Leaves the steady state on the calling thread.protected intrawWaitNextPeriod(RealtimeThread thread) Sleeps the calling thread to its next release.voidsetMemoryLimit(long bytes) Caps the memory of the process.start(String name, RealtimeParameters params, RealtimeTask task) Starts a real-time thread runningtask.
-
Field Details
-
FEATURE_SCHEDULING
public static final int FEATURE_SCHEDULINGReal-time scheduling (SCHED_FIFOon Linux).- See Also:
-
FEATURE_MEMORY_LOCK
public static final int FEATURE_MEMORY_LOCKLocking the process's memory so it is never paged out (lockMemory()).- See Also:
-
FEATURE_GC_ISOLATION
public static final int FEATURE_GC_ISOLATIONReal-time threads are not paused by the garbage collector.- See Also:
-
FEATURE_ALLOCATION_CHECK
public static final int FEATURE_ALLOCATION_CHECKAllocation in a cycle is detected at run time.- See Also:
-
FEATURE_PREEMPT_RT_KERNEL
public static final int FEATURE_PREEMPT_RT_KERNELThe kernel is aPREEMPT_RTkernel, which bounds its own latency.- See Also:
-
FEATURE_CPU_AFFINITY
public static final int FEATURE_CPU_AFFINITYThreads can be pinned to a CPU.- See Also:
-
APPLIED_SCHEDULING
protected static final int APPLIED_SCHEDULINGrawEnter(RealtimeThread, int, int, boolean)result bit: scheduling applied.- See Also:
-
APPLIED_AFFINITY
protected static final int APPLIED_AFFINITYrawEnter(RealtimeThread, int, int, boolean)result bit: CPU pinned.- See Also:
-
APPLIED_ISOLATION
protected static final int APPLIED_ISOLATIONrawEnter(RealtimeThread, int, int, boolean)result bit: other threads moved off.- See Also:
-
-
Constructor Details
-
Realtime
protected Realtime()Ports construct subclasses; applications callgetInstance().
-
-
Method Details
-
getInstance
Returns the real-time entry point of the current platform. Nevernull: where nothing is installed this is the best-effort Java implementation. -
install
Makesrealtimethe instancegetInstance()returns;nullrestores the default.Displayinstalls the port's instance when it starts and the backend installs its own, which is why this class never namesDisplay. -
isSupported
public boolean isSupported(int feature) truewhen the platform provides the feature, one of theFEATURE_constants. -
getSupportedFeatures
protected int getSupportedFeatures()Bit mask of theFEATURE_constants this platform provides. The default provides none. -
start
Starts a real-time thread running
task.Parameters
-
name: the thread's name, for logs and debuggers -
params: its scheduling; copied, so later changes do not affect it -
task: the work it runs
Returns
the running thread
-
-
lockMemory
public boolean lockMemory()Locks every page the process has and will have into memory, so a period never waits for one to be paged in. Call it early: it also makes every later allocation of memory resident at once.
Returns
truewhen the memory was locked;falsewhere unsupported or refused (Linux needsCAP_IPC_LOCKor a large enoughmemlocklimit) -
setMemoryLimit
public void setMemoryLimit(long bytes) Caps the memory of the process. After a collection that leaves the process above
bytes, a normal thread that asks for more memory gets anOutOfMemoryErrorat once, instead of waiting for collections that cannot free enough -- a failure the application can handle, in place of a device that slows to a crawl. Real-time threads are never refused: they do not allocate.The limit is on the process's resident memory, because that is the memory a device runs out of; it includes memory the heap holds and has not returned yet. An allocation is refused when a collection leaves the process over the limit, or without waiting for one once the process is a quarter over it. Linux only; elsewhere this does nothing.
Parameters
bytes: the limit, or 0 for none
-
rawEnter
Makes the calling thread real-time.
Returns
the
APPLIED_bits for what took effect, or a negative errno -
rawLeave
Returns the calling thread to normal scheduling. -
rawStartPeriod
Starts the periodic clock on the calling thread; the first release is one period from now. -
rawWaitNextPeriod
Sleeps the calling thread to its next release.
Returns
how many releases were missed
-
rawFreeze
Enters the steady state on the calling thread: from here an allocation beyondbudgetper period throwserror. The default has no run-time check. -
rawThaw
Leaves the steady state on the calling thread. Safe to call when not frozen. -
rawStatistics
Copies the calling thread's statistics intoout(RealtimeStatistics.COUNTvalues). -
rawLastViolation
The class of the allocation that ended the calling thread's last steady state, ornull. -
rawLockMemory
protected int rawLockMemory()Locks the process's memory. Returns 0 or a negative errno; the default answers -38 (ENOSYS). -
rawSetMemoryLimit
Installs the memory limit;erroris the instance to throw. The default does nothing.
-