CSE 522S: Studio 9

Real-Time Scheduling


Frodo could see them, small black figures in rank upon rank, marching swiftly and silently, passing outwards in an endless stream.

The Two Towers, Book IV, Chapter 8

Linux's real-time scheduling classes are for processes that require a great deal of control over how they execute. They can be used to define programs that execute in very specific ways, and are even used preempt the operating system kernel.

In this studio, you will:

  1. Write a program that uses the real-time scheduler
  2. Use the kernel tracer to examine how this program runs

Please complete the required exercises below, as well as any optional enrichment exercises that you wish to complete.

As you work through these exercises, please record your answers, and when finished email your results to eng-cse522@email.wustl.edu with the phrase Real-Time Scheduler in the subject line.

Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.


Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.

  2. First, we'll need a program to run as a real-time workload. In the last studio you created an infinite-loop program, which we'll modify to use here. One problem / feature is that a real-time workload is capable of preempting the kernel itself- this can make it impossible for the kernel to stop misbehaving programs, so in general it's a very bad idea to create such programs with infinite loops. Rather than using an infinite loop, modify your program so that, rather than looping forever, it increments a loop index to five hundred million (500,000,000). This will provide a CPU bound task that's guaranteed to finish.

    NOTE: Modern compilers are smart enough to optimize your loop away. Turn off optimizations for this exercise. With no optimization, on the 900 MHz Raspberry Pi 3, the instructor's program runs for about five seconds. For -O1 it runs for about a half second. For any higher optimization level the program returns immediately. Use the time command to ensure that your program runs for around five seconds.

  3. Now, use the trace-cmd command to record sched_switch events during an execution of your program. Recall that the synatx for this is "sudo trace-cmd record -e sched_switch ./your_program arg1 arg2 ... ". Then use Kernelshark to inspect the trace.

    Examine how your program executes. List three processes that interefere with the execution of your program. Make a copy of your trace to inspect later- next time we run trace-cmd it will overwrite this one.

  4. Modify your workload program so that it sets and uses the SCHED_RR scheduling class. This program should take two arguments- the first should specify the core to execute upon, and the second should specify the real-time scheduling priority.

    To do so, you should use the function sched_setscheduler() that is documented at man sched_setscheduler. The required data structure, sched_param, is also documented at that page. Be sure to check the return value from this function for success, and print out an appropriate error message in the event of failure.

  5. Run your program under trace-cmd with a real-time priority of one. Inspect the output in Kernelshark. What do you notice? Do any processes preempt your program? If so, which ones?

  6. Compare this execution trace to your original non-real-time trace. Is there any qualitative difference in how these interruptions occur?

  7. Filter the text box to only show events from the processor that your program used. To do so, go to the Filter menu and select list CPUs. How many sched_switch events were recorded on this CPU?

    Filter your list to a different CPU. How many sched_switch events were recorded there?

  8. Use the command ps -e -o cmd,rtprio to get a list of all processes on the system and their real-time priorities. A dash in the priority column means that this process does not have a real-time priority.

    Which real-time priorities do you see used? Give two processes with a real-time priority and speculate why they deserve a real-time priority.

  9. Run your program again with a real-time priority of 99. How many sched_switch events occur on your program's processor? Is your program ever preempted? If so, when and where is it preempted?

  10. Our next goal is to execute multiple simultaneous real-time processes together, but this is slightly trickier than you might think. If you create one real-time process, it will be impossible to create a second real-time process on that same processor until the first one finishes. Why is this?

  11. Make a copy of your real-time workload program. Modify it so that it takes a third argument, which will be the number of real-time tasks to create. Using this value, insert appropriate calls to the fork() function. This function should be called AFTER you have set the program's real-time priority, but BEFORE you start executing your work loop.

  12. Use your modified program to create three simultaneous real-time workloads. Trace the execution, and inspect the trace in Kernelshark. What do you see? Use the markers to measure the length of a round-robin time-slice. Recall that you can set marker A with a left mouse click, and set marker B with shfit + left mouse click.

    Things to turn in


Optional Enrichment Exercises

  1. Linux contains two other real-time scheduling classes, called SCHED_FIFO and (much more recently) SCHED_DEADLINE. Under the former policy, tasks are allowed to run to completion or until they give up the processor with sched_yield(). Under the latter policy, tasks are given deadlines for completion, and scheduled in order to best meet those deadlines. Try them out!