Getting Started with Real-Time Scheduling

in

I have received some questions lately about how to get started with Real-Time, and how to make your application take advantage of Real-Time. In particular with regard to process scheduling. I'd like to share some of the basics here, with some references for more reading.

Real-Time Scheduling Overview

Real-Time scheduling policies provide more control over what gets run when. With the proper privileges, you can specify the priority of not only your application threads, but also the critical system service threads, like hard and soft interrupt handlers. With this power, comes great responsibility! It is very easy to mis-configure a real-time system and render it unresponsive.

Real-Time processes run under either SCHED_FIFO or SCHED_RR policies. These processes are treated differently by the scheduler. SCHED_FIFO processes have a real-time priority, and do not have a time-slice. This means that they will run until they are either preempted by a higher priority real-time process or they voluntarily release the CPU, either by explicitly sleeping, or blocking on a lock or some other synchronous blocking call. SCHED_FIFO tasks are globally scheduled, meaning the scheduler ensures that the NR_CPUs highest priority runnable SCHED_FIFO tasks are running on the CPUs at any given time. For example, if a priority 90 process is preempted on a CPU by a priority 91 process, the system checks to see if the priority 90 process would preempt any processes on the other CPUs, if so, it is moved and continues running. SCHED_RR processes have a real-time priority, but they also have a timeslice. The scheduler schedules these processes in a round-robin fashion out of the local runqueue. This may produce unexpected results if you were hoping for global round-robin behavior, but round-robin'ing tasks from all the system runqueues would require a lot of extra logic (rather than relying on the FIFO nature of the runqueue priority arrays). A final key difference for both policies: real-time processes are never placed on the expired array. This affects the behavior of things like sched_yield(), which is basically a no-op on the highest priority real-time process on the system. In my experience, SCHED_FIFO is a much more common real-time scheduler policy.

Privileges

You can typically do everything you need to as the root user, but sometimes you may not want to grant that much access to all your real-time processes. Recent versions of pam allow you to grant rt scheduling privileges to certain users or groups. The following line added to a recent version pam will allow members of the realtime group to set their rt priorities:

@realtime       -       rt_priority     100

Leveraging Real-Time

There are a couple of different ways to make use of real-time scheduling. You can either build it in to your application, which certainly gives you the most fine grained control, particularly with threaded applications. Alternatively you can use tools like chrt to set the policy and priority of any process.

Setting Real-Time Priorities Programmatically

#include <stdio.h>
#include <sched.h>

int main()
{
    struct sched_param sp;

    sp.sched_priority = 90;
    if (sched_setscheduler(0, SCHED_FIFO, &sp) != 0) {
            perror("sched_setscheduler");
            return -1;
    }
    printf("hello real-time!\n");
    return 0;
}

Creating Real-Time Threads Programmatically

#include <pthread.h>
#include <stdio.h>

void * func(void *arg)
{
    // do your real-time stuff here...
    printf("hello real-time!\n");
    return NULL;
}

int main()
{
    pthread_t pthread;
    pthread_attr_t attr;
    struct sched_param param;
    int ret;

    param.sched_priority = 90;
    pthread_attr_init(&attr);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedparam(&attr, ¶m);
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
    if ((ret = pthread_create(&pthread, &attr, func, NULL))) {
        printf("pthread_create failed: %d (%s)\n", ret, strerror(ret));
        pthread_attr_destroy(&attr);
        return -1;
    }
    pthread_attr_destroy(&attr);

    return 0;
}

Using chrt

Alternatively, you can change an existing non-real-time application to run as real-time with the chrt command.

$ chrt -f -p 90 <PID>

You can use chrt to view the real-time attributes of a task as well, or you can look at the priority of all the processes on the system, with something like:

$ ps -eLo pid,rtprio,comm

References

  1. http://rt.wiki.kernel.org
  2. chrt(1)
  3. SCHED_SETSCHEDULER(2)

Comments

re

Different people have talents to perform a smashing theme related to this good post but hundreds of them are pressured for time for that deal. Thence, any thesis service will be able to aid every person with the research methodology dissertation formatting. And in fact, that will economize some time.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.
  • You may use [acidfree:xx] tags to display acidfree videos or images inline.

More information about formatting options

Back to top