3

I would like to know why preemption does not solve priority inversion problem?
If we have preemptive kernel. Then why priority inversion problem does not get solved?

Mat
  • 202,337
  • 40
  • 393
  • 406
Rasmi Ranjan Nayak
  • 11,510
  • 29
  • 82
  • 122
  • 1
    Please explain why do you think it does solve... – lvella Jul 05 '12 at 06:55
  • 1
    This question belongs on programmers.stackexchange.com – RedX Jul 05 '12 at 06:57
  • @lvella: I think so because the priority inversion problem happens when `highest priority task` is waiting and `medium priority task` arrives. In `preemption` highest priority task preempts the lower priority task then there is `no question of` priority inheritance, as far as I think. Don't you think so? – Rasmi Ranjan Nayak Jul 05 '12 at 06:58
  • @RedX: Why do you think that, this question belongs to programmers.stackexchange.com? – Rasmi Ranjan Nayak Jul 05 '12 at 07:00
  • Why to close this question? Please tell me or advice me. – Rasmi Ranjan Nayak Jul 05 '12 at 07:01
  • @RasmiRanjanNayak That is not priority inversion, I think you didn't really understood the problem. – lvella Jul 05 '12 at 07:02
  • I believe it belongs there because it is not a question about a code problem you have but more general about algorithms, which IMHO fit programmers better. – RedX Jul 05 '12 at 08:13
  • 3
    @RedX No, algorithms and operating system theory belong here, **not** programmers. Programmers is about interpersonal relations and business decisions. – Potatoswatter Jul 05 '12 at 09:01
  • @Potatoswatter Oops, i might have gotten something mixed up then, sry. – RedX Jul 05 '12 at 10:50
  • The only other candidate site this could belong on is Theoretical Computer Science, but I think it's more appropriate here, especially since there's not any deep theoretical interest to the question. – R.. GitHub STOP HELPING ICE Jul 05 '12 at 11:17

6 Answers6

8

Ok, let's say we have two processes. Let's also assume that the process which has lower priority gets a lock. When the higher-priority process becomes ready, it preempts the other process. If the higher-priority process needs that lock, it can't get it due to the other process which has lower priority. That means, lower-priority process blocks the higher-priority one. It prevents higher-priority process from running. This is called "Priority Inversion".

Obviously, preemption is not a solution for priority inversion. The solution is "Priority Inheritance". It means that we should temporarily increase the process's priority whenever it acquires a lock that is also needed by a higher-priority process. It should be the highest-priority process among the other processes which might want the same lock.

  • Windows uses a simple hack to help avoid starvation caused by issues like priority inversion. [`The Windows NT scheduler solves this problem by randomly boosting the priority of threads that are ready to run (in this case the low priority lock-holders). The low priority threads run long enough to let go of their lock (exit the critical section), and the high- priority thread gets the lock back. If the low-priority thread doesn't get enough CPU time to free its lock the first time, it will get another chance on the next scheduling round.`](http://support.microsoft.com/kb/96418) – Alexey Frunze Jul 05 '12 at 09:34
  • Actually, increasing the priority *whenever it acquires a lock* is not what priority inheritance means, and is probably a bad idea. Priority inheritance means increasing the priority only when a higher-priority thread is waiting to obtain the lock. – R.. GitHub STOP HELPING ICE Jul 05 '12 at 11:19
  • @ R.. - Yes, you're right. I tried to tell the same thing in my last sentence. Increasing the priority should not block the other higher-priority processes which have nothing to do with our lock. – aydinkahriman Jul 05 '12 at 11:27
  • @R.. That protocol is priority ceiling. Where a lock has a inherent priority to which the thread is raised when it acquires the lock. This is done mostly on real-time OS when you know beforehand which priorities your threads have and who needs what lock. – RedX Jul 06 '12 at 07:13
  • I'm not downvoting or anything but I still think it's unclear. It's not "acquiring a lock needed by a higher-priority process" that increases the thread's priority; in fact, acquiring such a lock is impossible unless you mean a lock which may be needed by a higher-priority process *later*. It's the act of the higher-priority process subsequently waiting on the lock that raises the priority. – R.. GitHub STOP HELPING ICE Jul 06 '12 at 12:36
  • 1
    Sigh. IMO this is not priority inversion, the 2 processes share a resource and this is the expected behavior. The *priority inversion* comes in when a 3rd process (in between the other 2 in priority) which doesn't share the resource is ready to run. Now it preempts the low priority resource-holding task, further delaying when the high priority task will eventually run. Almost every other answer below this accepted answer got it right. Also, I believe you described "priority ceiling", not "priority inheritance". – Dan Jul 08 '12 at 13:56
5

Let 3 threads A, B, C with respective priority High, Medium, Low.

C gets the processor and take a lock L. Then B is waken up by some events and preempts C. Now A is waken up and get the processor by preempting B. A wants the lock L, but fails because L is already owned by C. A gets preempted because of lock unavailability and gives back the processor to B. We have to wait for B to complete, which will eventually ends up in giving back the processor to C. C will complete and release the lock, which will finally wake up A.

This is a priority inversion because B runs whereas we have a thread A in the system with a higher priority waiting for completion of a lower priority thread (C in this case).

By the way, the solution is priority inheritance.

Benny
  • 4,095
  • 1
  • 26
  • 27
  • 1
    [It can be fixed with a hack too.](http://support.microsoft.com/kb/96418). Not the best solution, but a solution nonetheless. – Alexey Frunze Jul 05 '12 at 09:36
  • 2
    A colleague of mine once had an interesting idea that the scheduler could keep a DAG (well, you'd hope it's acyclic) of the dependencies between threads currently blocked on synchronization objects owned by other threads. Then whenever you want to schedule A but it's blocked, you instead follow the DAG to a leaf node (in this case C), and run that instead of A. He never implemented it though, and there were a bunch of complications that weren't going to get solved without a detailed design. It had the potential to be "fairer" than simple priority inheritance, esp. with WaitForMultipleObjects. – Steve Jessop Jul 05 '12 at 09:51
  • These points are interesting and worth some deeper digging. Personally, I feel pretty comfortable with the idea of not sharing locks between threads of different priority. But I am mainly working on critical/embedded systems and constraints are differents. – Benny Jul 05 '12 at 11:52
1

Preemption means taking away the processor so that a task no longer runs.

This is not enough, because the low priority task holds a resource which the high priority task needs.

Now if the resource could just be taken away (a different kind of "preemption") then this would indeed solve the priority inversion. But this is usually not possible, because the half-finished action of the low priority task would lead to inconsistencies.

starblue
  • 55,348
  • 14
  • 97
  • 151
0

Suppose you have 3 processes:

  • A - high priority
  • B - normal priority
  • C - low priority

and also that A and C both uses, say, the same file (this could be any shared resource) whose usage must be synchronized.

Now suppose neither A and B are ready to run, and C runs and obtains the lock to use the file. While C was holding the lock to the file, A gets ready to run, and the operating system preempts C, and runs A. A executes to the point it is also in need of the file, and when it tries to obtain the lock, it is blocked because C is holding the lock. If in mean time B got ready to run, it will be executed instead of A because A is not ready to run. In order for A to be ready, the file lock must be released by C, and C won't run and release the lock because higher priority process B is running. Thus A is waiting for C whose in turn is waiting for B. Just preempting B in this situation would do no good, because A is not ready, and won't be unless C runs, and C can not run because the just preempted higher priority B is ready to run.

lvella
  • 12,754
  • 11
  • 54
  • 106
0

From Wiki

Consider,

L --> Low Priority Task
H --> High Priority Task
M --> Medium Priority Task
R --> Resource

Step 1: L acquires R
Step 2: H Requests R(Currently in use with L. so H will wait for L to relinquish R.)
Step 3: M Arrives(M is a non-blocked Task. i.e It does not requires R)
Step 4: L is preempted by M.(so L can't relinquish R. Due to this, H can't run.)

After M finished it's execution, L will relinquishes R. After that only H can continue. In the scenario above, a task with medium priority(M) ran before a task with high priority(H).

This is the actual priority inversion scenario in preemptive kernel.

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
0

priority inversion is a problematic scenario in scheduling when a higher priority task is indirectly preempted by a lower priority task effectively "inverting" the relative priorities of the two tasks.

Consider there is a task L, with low priority. This task requires resource R. Consider that L is running and it acquires resource R. Now, there is another task H, with high priority. This task also requires resource R. Consider H starts after L has acquired resource R. Now H has to wait until L relinquishes resource R. Everything works as expected up to this point, but problems arise when a new task M (which does not use R) starts with medium priority during this time. Since R is still in use (by L), H cannot run. Since M is the highest priority unblocked task, it will be scheduled before L. Since L has been preempted by M, L cannot relinquish R. So M will run till it is finished, then L will run - at least up to a point where it can relinquish R - and then H will run. Thus, in the scenario above, a task with medium priority ran before a task with high priority, effectively giving us a priority inversion.

Pratik
  • 77
  • 1
  • 1
  • 11