How it works...

Linux has several scheduling policies that it applies to application processes and threads. SCHED_OTHER is the default Linux time-sharing policy. It is intended for all threads and does not provide real-time mechanisms.

In our application, we use another policy, SCHED_FIFO. This is a simple scheduling algorithm. All threads that use this scheduler can only be preempted by a thread with a higher priority. If the thread goes to sleep, it is placed at the back of the queue of those threads with the same priority.

The priority of a thread with a SCHED_FIFO policy is always higher than the priority of any thread with a SCHED_OTHER policy, and as soon as a SCHED_FIFO thread becomes runnable, it immediately preempts a running SCHED_OTHER thread. From a practical standpoint, if there is only one SCHED_FIFO thread running in the system, it can use as much CPU time as it requires. The deterministic behavior and high priority of the SCHED_FIFO scheduler make it a good fit for real-time applications.

To assign a real-time priority to a thread, we define a ConfigureRealtime function. This accepts two parameters—a thread ID and the desired priority:

void ConfigureRealtime(pthread_t thread_id, int priority) {

The function populates data for the pthread_setschedparam function that uses the low-level API of the operating system to change the scheduler and the priority of a thread:

    if (pthread_setschedparam(thread_id,
SCHED_FIFO, &sch)) {

We define a Measure function that runs a busy loop, invoking a nanosleep function with parameters requiring it to sleep for 10 nanoseconds – way too short to yield execution to another thread:

    struct timespec delay{0, 10};
for (int i = 0; i < 100000; i++) {
nanosleep(&delay, nullptr);
}

This function captures timestamps before and after the loop and calculates the elapsed time in seconds:

    struct timespec ts;
timespec_get(&ts, TIME_UTC);
double delta = (ts.tv_sec - prev.tv_sec) +
(double)(ts.tv_nsec - prev.tv_nsec) / 1000000000;

Next, we define the RealTimeThread function as a wrapper around the Measure function. This sets the priority of the current thread to real time and immediately invokes Measure:

    ConfigureRealtime(pthread_self(), 1);
Measure(txt);

In the main function, we start two threads, passing text literals as parameters to differentiate their output. If we run the program on a Raspberry Pi device, we can see the following output:

Real-time threads took four times lesser time because this was not preempted by normal threads. This technique can be efficiently used to meet the soft real-time requirements in the Linux environment.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.190.93