Skip to content

Retif – Real-Time Framework for POSIX Systems. A tool for supporting real-time computing on Linux. This tool focuses on improving the usability of real-time capabilities for user applications thinking towards a declarative-reservation paradigm.

License

Notifications You must be signed in to change notification settings

gabriserra/retif

Repository files navigation

Contributors Issues Bugs License Documentation

Retif – Real-Time Framework for POSIX Systems

Retif (or ReTiF) is a novel framework that enables unprivileged access to the real-time features of Unix-based operating systems in a controlled manner. The API it provides improves the usability of real-time capabilities of the underlying OS with more guarantees than what one would normally get using directly the OS API.

The main strength of the framework is its declarative approach, in which applications simply declare the kind of tasks that they would like to run with real-time privileges and let the framework do its "magic" to accomodate their requests.

Publications

The framework has been the subject of two publications from Scuola Superiore Sant'Anna, Pisa:

The presentation of the conference paper above can be found on YouTube. Please refer to the journal paper above for a detailed discussion on Retif internals. Feel free to contact any of the authors above for a copy.

Getting Started

We provide both binaries and sources to install Retif on your system. Bear in mind that not all platforms may be supported equally. Retif is built and tested on Ubuntu 20.04 and on Fedora 34.

Installing from binaries

Releases page contains binary and source packages for Retif. All packages are not self-updating, so you may want to checkout the releases page from time to time.

  • On Debian-based distributions, you can use the provided .deb package to install all Retif components and its dependencies.

  • On Red Hat and Fedora-based distributions, you can use the provided .rpm package to install all Retif components and its dependencies.

  • For all other distributions, try the tar/zip archives.

Installing from sources

Building Retif from sources requires a reasonably recent version of CMake to be installed, which will be used to build all the components of the framework and to install them in the appropriate locations. In addition, libyaml library must be installed on your system (with its headers as well).

To install all required dependencies:

  • On Ubuntu and Debian-based distributions
    sudo apt install build-essential cmake libyaml-dev
  • On Fedora and Red Hat-based distributions
    sudo dnf install make automake gcc cmake libyaml-devel

Once you have all dependencies sorted out, follow these steps:

  1. Clone the repo
    git clone https://github.com/gabriserra/retif
    cd retif
  2. Run the build script (it will invoke CMake for you)
    ./m build
  3. Install (requires superuser privileges)
    sudo ./m install

Usage

Applications that want to leverage the functionality provided by Retif must use the Retif library (libretif) to do so, which provides a simple yet effective declarative API for real-time applications. Following is an overview of Retif ecosystem architecture.

Retif architecture

Retif is based on a daemon-library architecture, in which there is a centeral decision authority, the Retif daemon (retifd), to which all requests from unprivileged user applications are forwarded. The daemon performs a set of checks useful to provide some real-time guarantees to user applications and it is the only component in Retif that interacts with the underlying OS to set scheduling properties of the real-time tasks declared by user applications.

The behavior of the daemon can be extended using a set of plugins which are dynamically loaded by the daemon at startup according to a user-provided configuration. The daemon is in fact implemented as much OS-independent and scheduling algorithm-independent as possible, leaving all OS-specific and scheduling algorithm-specific operations to plugins. Each plugin is typically associated to a specific OS/scheduling algorithm (some plugins may support multiple OSes as long as they share similar APIs, like POSIX).

For each request received by the daemon through the libretif API, the currently loaded plygins are interrogated to analyze the request and determine whether they can serve it (i.e. set the scheduling parameters of the requesting application in order to satisfy its requirements) or not. If at least one plugin can serve the request, the user application receives a positive response. Refer to the plugins directory for more info.

Running the Retif daemon

NOTE: Support for the retif service on Fedora and Red Hat systems is not available as of now, you should start the retifd command yourself in background.

Retif relies on a daemon application to run in the background. To start the daemon you can use service or systemctl:

sudo service retif start

You can check that the daemon is running by checking the exit code of the status command, like this:

(
  service retif status &&
    echo 'Retif daemon is running'
) || echo 'Retif daemon is not running'

or alternatively you can check whether the retifd application is running (works also if not started using the service command):

(
  pgrep retifd >/dev/null &&
    echo 'Retif daemon is running'
) || echo 'Retif daemon is not running'

Configuring the Retif daemon

The set of plugins loaded by the daemon at startup depends on the daemon configuration file, which is typically found in /etc/retif.conf. Refer to the content of the conf directory for more details.

Retif API

The Retif library provides a simple API that streamlines communication with the Retif daemon.

The following table shows the main functions exposed by the library:

Function Description
rtf_task_create Performs task admission test and applies the specified rtf_params to the new task.
rtf_task_change Performs a new task admission test with the specified rtf_params; in case of failure the task maintains its old parameters.
rtf_task_release Releases a task, freeing its resources and detaching the attached POSIX thread, if any.
rtf_task_attach Attaches a POSIX thread id to the given task.
rtf_task_detach Detaches the POSIX thread assigned to a task; after this call, the thread runs with a non real-time priority and the task reference can then be attached to another POSIX thread.
rtf_connections_info Retrieve the number of clients currently connected to the daemon.
rtf_connection_info Retrieve info about a connected client.
rtf_tasks_info Retrieve the number of task accepted by the daemon.
rtf_task_info Retrieve info about an accepted task.
rtf_tasks_info Retrieve the number of registered plugins.
rtf_task_info Retrieve info about a registered plugin.
rtf_plugin_cpu_info Retrieve aggregate data relative to a specified CPU under the control of a registered plugin.

Applications can declare the scheduling parameters of each real-time task by filling an instance of the opaque type rtf_params, using the functions described in table below:

Parameter Unit Getter / Setter
Runtime microseconds rtf_params_get_runtime / rtf_params_set_runtime
Desired Runtime microseconds rtf_params_get_des_runtime / rtf_params_set_des_runtime
Period microseconds rtf_params_get_period / rtf_params_set_period
Relative Deadline microseconds rtf_params_get_deadline / rtf_params_set_deadline
Priority - rtf_params_get_priority / rtf_params_set_priority
Scheduling Plugin - rtf_params_set_scheduler / rtf_params_get_scheduler
Ignore Admission Test - rtf_params_ignore_admission

For a more complete description of Retif library API, please refer to the online documentation.

Retif API Example

The following code provides a simple overview of how applications that leverage Retif API are written.

#include <retif.h>

void retif_thread()
{
    /* Task representation */
    struct rtf_task t = RTF_TASK_INIT;

    /* Task parameters */
    struct rtf_params p = RTF_PARAM_INIT;

    /* Connect to the daemon via a UNIX socket */
    if (rtf_connect() == RTF_CONNECTION_ERR)
        return; /* Unable to connect to the daemon. */

    /* Set task parameters */
    rtf_params_set_period(&p, T_PERIOD);
    rtf_params_set_runtime(&p, T_RUNTIME);
    rtf_params_set_des_runtime(&p, T_DES_RUNTIME);
    rtf_params_set_deadline(&p, T_DEADLINE);

    /* Test for admission */
    int res = rtf_task_create(&t, &p);

    /* If admission failed, we can retry with different
     * parameters */
    if (res == RTF_FAIL)
        return;
    else if (res == RTF_CONNECTION_ERR)
        return; /* Communication failed */

    /* res = RTF_OK */

    /* On success we attach an execution flow to the task
     * specification */
    rtf_task_attach(&t, getpid());

    /* Signals that a task begins its execution */
    rtf_task_start(&t);

    while (!computation_ended())
    {
        /* Task runs mandatory actions */
        mandatory_computation();

        /* Enabling optional computation depending on the
         * accepted runtime */
        if (rtf_task_get_accepted_runtime(&t) > T_RUNTIME)
            optional_computation();

        /* Suspend execution waiting for the next period */
        rtf_task_wait_period(&t);
    }

    /* Cleanup */
    rtf_task_release(&t);
}

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributors

The list of contributors can be found in the contributors of the project.

We want to thank Prof. Tommaso Cucinotta for his extensive support to the work. Without him, the framework would not exist at all.

License

The project comes with a GPLv3 license. If you want to use this code, you can do without limitation but you have to document the modifications and include this license. Read more here.

Citation

If you want to cite, please refer to:

@inproceedings{serraetal:2020:isorc,
  doi       = {10.1109/isorc49007.2020.00013},
  url       = {https://doi.org/10.1109/isorc49007.2020.00013},
  year      = {2020},
  month     = may,
  publisher = {{IEEE}},
  author    = {Gabriele Serra and Gabriele Ara and Pietro Fara and Tommaso Cucinotta},
  title     = {An Architecture for Declarative Real-Time Scheduling on Linux},
  booktitle = {2020 {IEEE} 23rd International Symposium on Real-Time Distributed Computing ({ISORC})}
}

@article{serraetal:2021:jsa,
  doi       = {10.1016/j.sysarc.2021.102210},
  url       = {https://doi.org/10.1016/j.sysarc.2021.102210},
  year      = {2021},
  month     = sep,
  publisher = {Elsevier {BV}},
  volume    = {118},
  pages     = {102210},
  author    = {Gabriele Serra and Gabriele Ara and Pietro Fara and Tommaso Cucinotta},
  title     = {{ReTiF}: A declarative real-time scheduling framework for {POSIX} systems},
  journal   = {Journal of Systems Architecture}
}

About

Retif – Real-Time Framework for POSIX Systems. A tool for supporting real-time computing on Linux. This tool focuses on improving the usability of real-time capabilities for user applications thinking towards a declarative-reservation paradigm.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published