The default scheduling policy in Xenomai is preemptive priority-based FIFO scheduling. Hence, execution of a low-priority task is interrupted when a high-priority is ready to execute. When multiple processes of the same priority are ready to run, the default is that the task which was first queued in the waiting queue of the scheduler, is run first (FIFO ordering), and run to its end. In the next exercise we show how this can be changed to round-robin scheduling of tasks with equal priority.
The following are the primary objectives of this exercise:
With a preemptive priority-based scheduler, each task has a priority and the kernel insures that the CPU is allocated to the highest priority task that is ready to run. This scheduling method is preemptive in that if a task that has a higher priority than the current task becomes ready to run, the kernel saves the context of the current tasks and switches to the context of the higher priority task. The Xenomai kernel has priority levels between the highest priority 99 and the lowest priority 1.
When creating a task with rt_task_create(..) one of the arguments to is the priority at which the task is to execute. The priority of a task can be changed by means of the following function:
int rt_task_set_priority (RT_TASK *task, int prio)
The next example program contains three tasks with different priorities. Each task has an execution of EXECTIME ns in which after each SPINTIME ns a message is printed. The CPU is kept busy by the function
void rt_timer_spin (RTIME ns)
which is a busy wait burning CPU cycles.
------------------------------------------------------------------------------------
/* ex06a.c */
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include
<native/task.h>
#include
<native/timer.h>
#include
<native/sem.h>
#include <rtdk.h>
#include <sys/io.h>
#define NTASKS 3
#define HIGH 52 /* high
priority */
#define MID 51 /* medium
priority */
#define
RT_TASK demo_task[NTASKS];
RT_
#define BASEPERIOD 0 // baseperiod 0 to get ns
#define EXECTIME 2e8
// execution time in ns
#define SPINTIME 1e7
// spin time in ns
void demo(void *arg)
{
RTIME starttime, runtime;
int num=*(int *)arg;
RT_TASK *curtask;
RT_TASK_
rt_printf("Task : %d\n",num);
rt_sem_p(&mysync,TM_INFINITE);
runtime = 0;
while(runtime < EXECTIME) {
rt_timer_spin(SPINTIME); // spin cpu doing nothing
runtime = runtime + SPINTIME;
rt_printf("Running Task : %d
at ms : %d\n",num,runtime/1000000);
}
rt_printf("End Task : %d\n",num);
}
//startup code
void startup()
{
int i;
char
str[10] ;
// semaphore to sync task startup on
rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);
// set timing to ns
rt_timer_set_mode(BASEPERIOD);
for(i=0; i < NTASKS; i++) {
rt_printf("start task : %d\n",i);
sprintf(str,"task%d",i);
rt_task_create(&demo_task[i], str, 0,
50, 0);
rt_task_start(&demo_task[i], &demo,
&i);
}
// assign priorities to tasks
// (or in creation use 50+i)
rt_task_set_priority(&demo_task[0],
rt_task_set_priority(&demo_task[1],MID);
rt_task_set_priority(&demo_task[2],HIGH);
rt_printf("wake up all tasks\n");
rt_sem_broadcast(&mysync);
}
void init_xenomai() {
/* Avoids memory swapping for this program */
mlockall(
/* Perform auto-init of rt_print buffers if
the task doesn't do so */
rt_print_auto_init(1);
}
int main(int argc, char*
argv[])
{
printf("\nType CTRL-C to end this
program\n\n" );
// code to set things to run xenomai
init_xenomai();
//startup code
startup();
// wait for CTRL-c is typed to end the
program
pause();
}
------------------------------------------------------------------------------------
Execute the example program above and explain its output.
Experiment 6b.
Modify the program of 6a such that first task still has the lowest priority, but the other two tasks are running at the same high priority. Compare the output with that of 6a.
Modify the program of 6a such that the highest-priority task half-way its execution:
Explain the output.
Modify the program of 6a such
that each task at half-way of its execution changes its priority. The
first task changes it priority halfway to 40, the second task to 39 and the
third to 38. Explain the resulting output.
Last Updated: 29 August
2009 (
Created by:
h.kuppens@cs.ru.nl