Class Realtime

java.lang.Object
com.codename1.realtime.Realtime

public class Realtime extends Object

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_NICE or an rtprio limit.
  • 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 Details

  • Constructor Details

    • Realtime

      protected Realtime()
      Ports construct subclasses; applications call getInstance().
  • Method Details

    • getInstance

      public static Realtime getInstance()
      Returns the real-time entry point of the current platform. Never null: where nothing is installed this is the best-effort Java implementation.
    • install

      public static void install(Realtime realtime)
      Makes realtime the instance getInstance() returns; null restores the default. Display installs the port's instance when it starts and the backend installs its own, which is why this class never names Display.
    • isSupported

      public boolean isSupported(int feature)
      true when the platform provides the feature, one of the FEATURE_ constants.
    • getSupportedFeatures

      protected int getSupportedFeatures()
      Bit mask of the FEATURE_ constants this platform provides. The default provides none.
    • start

      public RealtimeThread start(String name, RealtimeParameters params, RealtimeTask task)

      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

      true when the memory was locked; false where unsupported or refused (Linux needs CAP_IPC_LOCK or a large enough memlock limit)

    • 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 an OutOfMemoryError at 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

      protected int rawEnter(RealtimeThread thread, int priority, int cpu, boolean isolate)

      Makes the calling thread real-time.

      Returns

      the APPLIED_ bits for what took effect, or a negative errno

    • rawLeave

      protected void rawLeave(RealtimeThread thread)
      Returns the calling thread to normal scheduling.
    • rawStartPeriod

      protected void rawStartPeriod(RealtimeThread thread, long periodNanos)
      Starts the periodic clock on the calling thread; the first release is one period from now.
    • rawWaitNextPeriod

      protected int rawWaitNextPeriod(RealtimeThread thread)

      Sleeps the calling thread to its next release.

      Returns

      how many releases were missed

    • rawFreeze

      protected void rawFreeze(RealtimeThread thread, int budget, RealtimeAllocationError error)
      Enters the steady state on the calling thread: from here an allocation beyond budget per period throws error. The default has no run-time check.
    • rawThaw

      protected void rawThaw(RealtimeThread thread)
      Leaves the steady state on the calling thread. Safe to call when not frozen.
    • rawStatistics

      protected void rawStatistics(RealtimeThread thread, long[] out)
      Copies the calling thread's statistics into out (RealtimeStatistics.COUNT values).
    • rawLastViolation

      protected String rawLastViolation(RealtimeThread thread)
      The class of the allocation that ended the calling thread's last steady state, or null.
    • rawLockMemory

      protected int rawLockMemory()
      Locks the process's memory. Returns 0 or a negative errno; the default answers -38 (ENOSYS).
    • rawSetMemoryLimit

      protected void rawSetMemoryLimit(long bytes, OutOfMemoryError error)
      Installs the memory limit; error is the instance to throw. The default does nothing.