rt_task_set_priority does not increase priority of other task

Harco Kuppens h.kuppens at cs.ru.nl
Wed Sep 16 20:12:49 CEST 2020


Hi,

I found a problem with rt_task_set_priority function which does not 
increase priority of another task.
However it works fine if you increase the priority of another task.

Below is an en example program and its output, and we run this program 
on xenomai 3.08.
The problem appears if we run the program on our xenomai image for the 
raspberry pi 3,
and is also appears in our virtual box image.
Both images can be found at :

  * http://www.cs.ru.nl/lab/xenomai/raspberrypi.html
  * http://www.cs.ru.nl/lab/xenomai/virtualbox.html

The easiest way is to run the virtualbox image.

The final question I have: is there an wrong usage of xenomai API in the 
example program,
or is this a bug in xenomai?

Hope somebody can help me with this problem.

Best regards,
Harco Kuppens

The following xenomai program has the problem:

    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <alchemy/task.h>
    #include <alchemy/sem.h>
    #include <alchemy/timer.h>

    #define NTASKS 3
    #define HIGH 52 /* high priority */
    #define MID 51 /* medium priority */
    #define LOW 50  /* low priority */

    RT_TASK demo_task[NTASKS];
    RT_SEM mysync;

    #define EXECTIME   2e8   // execution time in ns
    #define SPINTIME   1e7   // spin time in ns
    #define SLEEPTIME   1e9   // sleep time in ns

    void demo(void *arg)
    {
         int ret;
         RT_TASK *curtask;
         RTIME starttime, runtime;
         RT_TASK_INFO taskinfo;
         int num=*(int *)arg;
         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;

           // inquire current task
           curtask=rt_task_self();
           rt_task_inquire(curtask,&taskinfo);

           printf("Running Task  : %d  prio: %d at ms : %d
    \n",num,(int)taskinfo.prio,(int) runtime/1000000);

           /**
            * Halfway through the execution of the highest priority
    task, that task should:
            *  -  raise the priority of the middle-priority task with 10
            *  -  next immediately also raises the priority of the
    low-priority task with 10
            */
           if (num == 2 && runtime == EXECTIME/2)
           {
             printf("change prio task 0 to %d\n",LOW+10);
             ret=rt_task_set_priority(&demo_task[0],LOW+10);
             if ( ret != 0 ) printf("problem set on task 0 LOW+10 ret
    %d\n",ret);

             printf("change prio task 1 to %d\n",MID+10);
             ret=rt_task_set_priority(&demo_task[1],MID+10);

             if ( ret != 0 ) printf("problem set on task 1 MID+10  ret
    %d\n",ret);
           }
         }
         printf("End Task  : %d\n",num);
    }

    //startup code
    void startup()
    {
       int ret;
       RT_TASK_INFO taskinfo;
       int i;
       char  str[20] ;
       // semaphore to sync task startup on
       rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);

       for(i=0; i < NTASKS; i++) {
         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);
       }
       for(i=0; i < NTASKS; i++) {
         ret=rt_task_inquire(&demo_task[i],&taskinfo);
         if ( ret != 0 ) printf("problem rt_task_inquire\n");
         printf("Task name and prio : %s  %d \n",
    taskinfo.name,taskinfo.prio);
       }
       // assign priorities to tasks

       ret=rt_task_set_priority(&demo_task[0],LOW);
       if ( ret != 0 ) printf("problem set LOW\n");
       ret=rt_task_set_priority(&demo_task[1],MID);
       if ( ret != 0 ) printf("problem set MID\n");
       ret=rt_task_set_priority(&demo_task[2],HIGH);
       if ( ret != 0 ) printf("problem set HIGH\n");

       for(i=0; i < NTASKS; i++) {
         ret=rt_task_inquire(&demo_task[i],&taskinfo);
         if ( ret != 0 ) printf("problem rt_task_inquire\n");
         printf("Task name and prio : %s  %d \n",
    taskinfo.name,taskinfo.prio);
       }

       printf("wake up all tasks\n");
       rt_sem_broadcast(&mysync);
    }

    int main(int argc, char* argv[])
    {
       startup();
       printf("\nType CTRL-C to end this program\n\n" );
       pause();
    }


gives the following output:

    start task  : 0
    Task  : 0
    start task  : 1
    Task  : 1
    start task  : 2
    Task  : 2
    Task name and prio : task0  50
    Task name and prio : task1  50
    Task name and prio : task2  50
    Task name and prio : task0  50
    Task name and prio : task1  51
    Task name and prio : task2  52
    wake up all tasks
    Running Task  : 2  prio: 52 at ms : 10
    Running Task  : 2  prio: 52 at ms : 20
    Running Task  : 2  prio: 52 at ms : 30
    Running Task  : 2  prio: 52 at ms : 40
    Running Task  : 2  prio: 52 at ms : 50
    Running Task  : 2  prio: 52 at ms : 60
    Running Task  : 2  prio: 52 at ms : 70
    Running Task  : 2  prio: 52 at ms : 80
    Running Task  : 2  prio: 52 at ms : 90
    Running Task  : 2  prio: 52 at ms : 100
    change prio task 0 to 60
    Running Task  : 1  prio: 51 at ms : 10
    Running Task  : 1  prio: 51 at ms : 20
    Running Task  : 1  prio: 51 at ms : 30
    Running Task  : 1  prio: 51 at ms : 40
    Running Task  : 1  prio: 51 at ms : 50
    Running Task  : 1  prio: 51 at ms : 60
    Running Task  : 1  prio: 51 at ms : 70
    Running Task  : 1  prio: 51 at ms : 80
    Running Task  : 1  prio: 51 at ms : 90
    Running Task  : 1  prio: 51 at ms : 100
    Running Task  : 1  prio: 51 at ms : 110
    Running Task  : 1  prio: 51 at ms : 120
    Running Task  : 1  prio: 51 at ms : 130
    Running Task  : 1  prio: 51 at ms : 140
    Running Task  : 1  prio: 51 at ms : 150
    Running Task  : 1  prio: 51 at ms : 160
    Running Task  : 1  prio: 51 at ms : 170
    Running Task  : 1  prio: 51 at ms : 180
    Running Task  : 1  prio: 51 at ms : 190
    Running Task  : 1  prio: 51 at ms : 200
    End Task  : 1
    Running Task  : 0  prio: 50 at ms : 10
    Running Task  : 0  prio: 50 at ms : 20
    Running Task  : 0  prio: 50 at ms : 30
    Running Task  : 0  prio: 50 at ms : 40
    Running Task  : 0  prio: 50 at ms : 50
    Running Task  : 0  prio: 50 at ms : 60
    Running Task  : 0  prio: 50 at ms : 70
    Running Task  : 0  prio: 50 at ms : 80
    Running Task  : 0  prio: 50 at ms : 90
    Running Task  : 0  prio: 50 at ms : 100
    Running Task  : 0  prio: 50 at ms : 110
    Running Task  : 0  prio: 50 at ms : 120
    Running Task  : 0  prio: 50 at ms : 130
    Running Task  : 0  prio: 50 at ms : 140
    Running Task  : 0  prio: 50 at ms : 150
    Running Task  : 0  prio: 50 at ms : 160
    Running Task  : 0  prio: 50 at ms : 170
    Running Task  : 0  prio: 50 at ms : 180
    Running Task  : 0  prio: 50 at ms : 190
    Running Task  : 0  prio: 50 at ms : 200
    End Task  : 0
    change prio task 1 to 61
    Running Task  : 2  prio: 52 at ms : 110
    Running Task  : 2  prio: 52 at ms : 120
    Running Task  : 2  prio: 52 at ms : 130
    Running Task  : 2  prio: 52 at ms : 140
    Running Task  : 2  prio: 52 at ms : 150
    Running Task  : 2  prio: 52 at ms : 160
    Running Task  : 2  prio: 52 at ms : 170
    Running Task  : 2  prio: 52 at ms : 180
    Running Task  : 2  prio: 52 at ms : 190
    Running Task  : 2  prio: 52 at ms : 200
    End Task  : 2

    Type CTRL-C to end this program

-------------- next part --------------
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>

#define NTASKS 3
#define HIGH 52 /* high priority */
#define MID 51 /* medium priority */
#define LOW 50  /* low priority */

RT_TASK demo_task[NTASKS];
RT_SEM mysync;

#define EXECTIME   2e8   // execution time in ns
#define SPINTIME   1e7   // spin time in ns
#define SLEEPTIME   1e9   // sleep time in ns

void demo(void *arg)
{
    int ret;
    RT_TASK *curtask;
    RTIME starttime, runtime;
    RT_TASK_INFO taskinfo;
    int num=*(int *)arg;
    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;

      // inquire current task
      curtask=rt_task_self();
      rt_task_inquire(curtask,&taskinfo);

      printf("Running Task  : %d  prio: %d at ms : %d    \n",num,(int)taskinfo.prio,(int) runtime/1000000);

      /**
       * Halfway through the execution of the highest priority task, that task should:
       *  -  raise the priority of the middle-priority task with 10
       *  -  next immediately also raises the priority of the low-priority task with 10
       */
      if (num == 2 && runtime == EXECTIME/2)
      {
        printf("change prio task 0 to %d\n",LOW+10);
        ret=rt_task_set_priority(&demo_task[0],LOW+10);
        if ( ret != 0 ) printf("problem set on task 0 LOW+10 ret %d\n",ret);

        printf("change prio task 1 to %d\n",MID+10);
        ret=rt_task_set_priority(&demo_task[1],MID+10);

        if ( ret != 0 ) printf("problem set on task 1 MID+10  ret %d\n",ret);
      }
    }
    printf("End Task  : %d\n",num);
}

//startup code
void startup()
{
  int ret;
  RT_TASK_INFO taskinfo;
  int i;
  char  str[20] ;
  // semaphore to sync task startup on
  rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);

  for(i=0; i < NTASKS; i++) {
    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);
  }
  for(i=0; i < NTASKS; i++) {
    ret=rt_task_inquire(&demo_task[i],&taskinfo);
    if ( ret != 0 ) printf("problem rt_task_inquire\n");
    printf("Task name and prio : %s  %d \n", taskinfo.name,taskinfo.prio);
  }
  // assign priorities to tasks

  ret=rt_task_set_priority(&demo_task[0],LOW);
  if ( ret != 0 ) printf("problem set LOW\n");
  ret=rt_task_set_priority(&demo_task[1],MID);
  if ( ret != 0 ) printf("problem set MID\n");
  ret=rt_task_set_priority(&demo_task[2],HIGH);
  if ( ret != 0 ) printf("problem set HIGH\n");

  for(i=0; i < NTASKS; i++) {
    ret=rt_task_inquire(&demo_task[i],&taskinfo);
    if ( ret != 0 ) printf("problem rt_task_inquire\n");
    printf("Task name and prio : %s  %d \n", taskinfo.name,taskinfo.prio);
  }

  printf("wake up all tasks\n");
  rt_sem_broadcast(&mysync);
}

int main(int argc, char* argv[])
{
  startup();
  printf("\nType CTRL-C to end this program\n\n" );
  pause();
}


More information about the Xenomai mailing list