Cannot cause priority inversion in C ++

I am trying to call Priority Inversion in a small C ++ program for demo purposes, but I can’t: the low priority thread containing the mutex is not unloaded and continues to work in the critical section. This is what I do:

// let declare a global mutex
pthread_mutex_t my_mutex;
  ...

int main(int argc, char **argv) {
  ...
  pthread_t normal_thread;
  pthread_t prio_thread;

  pthread_mutexattr_t attr;
  pthread_mutexattr_init (&attr);
  pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_NONE);  // ! None !
  pthread_mutex_init(&my_mutex, &attr);

  // create first normal thread (L):
  pthread_create(&normal_thread, NULL, the_locking_start_routine, NULL);

  // just to help the normal thread enter in the critical section
  sleep(2);

  // now will launch:
  // * (M) several CPU intensive SCHED_FIFO threads with priority < 99
  // * (H) one SCHED_FIFO thread that will try to lock the mutex, with priority < 99

  // build Real Time attributes for the Real Time threads:
  pthread_attr_t my_rt_att;
  pthread_attr_init(&my_rt_att);

  // it was missing in the original post and it was also wrong:
  // even setting the SchedPolicy you have to set "InheritSched"
  pthread_attr_setinheritsched(&my_rt_att, PTHREAD_EXPLICIT_SCHED)

  pthread_attr_setschedpolicy(&my_rt_att, SCHED_FIFO);
  struct sched_param params;

  params.sched_priority = 1;
  pthread_attr_setschedparam(&my_rt_att, &params);

  pthread_create(&prio_thread, &my_rt_att, the_CPU_intensive_start_routine, NULL) 

  params.sched_priority = 99;
  pthread_attr_setschedparam(&my_rt_att, &params);

  // create one RealTime thread like this:
  pthread_create(&prio_thread, &my_rt_att, the_locking_start_routine, NULL)  //coma was missing

  ...
}

void *the_locking_start_routine(void *arg) {
  ...
  pthread_mutex_lock(&my_mutex);
  // This thread is on the critical section
  // ... (skipped)
  pthread_mutex_unlock(&my_mutex);
  ...
}

... But this will not work, I cannot get the desired priority inversion.

Here's what happens:

As I understand it, with a scheduler like Linux CFS, the non-real-time stream (SCHED_OTHER) will not work until there is a Real Time stream (SCHED_FIFO or SCHED_RR) in runnning mode. But I reached these threads at the same time:

  • (L) One non-real-time thread (SCHED_OTHER) blocking the mutex and consuming processor
  • (M) (SCHED_FIFO > 0) CPU
  • (H) (SCHED_FIFO )

(M), ... (L) - mutex , "M" .

, ?

g++ 4.5.2 Ubuntu Desktop 11.04 2.6.38-13.

+3
3
  • root?

  • sysctl? Ubuntu. - 0,95 1- :

    kernel.sched_rt_period_us = 1000000
    kernel.sched_rt_runtime_us = 950000
    

    . , .

: http://www.kernel.org/doc/Documentation/scheduler/sched-rt-group.txt

sched_rt_runtime_us -1, .

+3

Re: Invision Inversion ++- , : , , ...

. (, mutex), .

, , , : (L), (M) (H) .

L , H. L , H . : H L, - .

M . ; H L. M , L, L CPU.

, M , L. L , , H.

, M H.

L, M H: .

, .

+5

Most modern schedulers have a blocking protection that will change the priority for a time slice or two to prevent priority inversion, leading to deadlocks when they are found or considered suitable. Regardless of whether Linux works with any scheduler that you use with it, I do not know for sure. However, keep this in mind if you have not already done so.

+1
source

All Articles