software solution for critical section problem, Study notes of Operating Systems

4 algorithms for the critical section problem

Typology: Study notes

2015/2016

Uploaded on 12/29/2016

zawar_khan
zawar_khan 🇵🇰

4

(1)

1 document

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Algorithm #1 (Incorrect)
One approach to solving the problem might be to have the processes take turns
accessing the resource. Consider the following proposed solution for a two-process
problem:
/* i is this process; j is the other process */
while (true)
{
while (turn != i); /* spin until it’s my turn */
<<< critical section >>>
turn = j;
<<< code outside critical section >>>
}
To understand why this code is incorrect, we must consider the characteristics of a
solution that we discussed earlier.
This solution does ensure mutual exclusion, but it is not correct. The proposed
solution violates both the progress criteria and the bounded wait criteria:
Since the processes are forced strictly into alternating turns, one process could
be prevented from accessing an unused resource, simple because it was not its
turn.
Consider P0, a process that must be in the critical section 70% of the
time, and another process, P1, that must be in the critical section 1% of
the time. P1's infrequent use of the critical section will block P0 most of
the time (Progress criteria violated)
Consider also the termination of either process. When a process terminates, one
of two things is true: 1) it has the "turn", or it will get the "turn" again soon.
The problem is, if it isn't running, it can't give the "turn" back. When a process
ends, it takes its turn with it into an immortal existence. The other process is
forever blocked.
Observations of Algorithm #1
Algorithm #1 fails, in part, becuase it assumes both processes need equal
access ot the critical section. This isn't the case.
Algorithm #1 also fails because it blindly assumes the other process needs a
turn. This also isn't the case.
pf3
pf4

Partial preview of the text

Download software solution for critical section problem and more Study notes Operating Systems in PDF only on Docsity!

Algorithm #1 (Incorrect)

One approach to solving the problem might be to have the processes take turns accessing the resource. Consider the following proposed solution for a two-process problem:

/* i is this process; j is the other process */

while (true) { while (turn != i); /* spin until it’s my turn */

<<< critical section >>>

turn = j;

<<< code outside critical section >>> }

To understand why this code is incorrect, we must consider the characteristics of a solution that we discussed earlier. This solution does ensure mutual exclusion, but it is not correct. The proposed solution violates both the progress criteria and the bounded wait criteria:

  • Since the processes are forced strictly into alternating turns, one process could be prevented from accessing an unused resource, simple because it was not its turn. Consider P 0 , a process that must be in the critical section 70% of the time, and another process, P 1 , that must be in the critical section 1% of the time. P 1 's infrequent use of the critical section will block P 0 most of the time (Progress criteria violated)
  • Consider also the termination of either process. When a process terminates, one of two things is true: 1) it has the "turn", or it will get the "turn" again soon. The problem is, if it isn't running, it can't give the "turn" back. When a process ends, it takes its turn with it into an immortal existence. The other process is forever blocked.

Observations of Algorithm #

  • Algorithm #1 fails, in part, becuase it assumes both processes need equal access ot the critical section. This isn't the case.
  • Algorithm #1 also fails because it blindly assumes the other process needs a turn. This also isn't the case.
  • Mutual exclusion is assured by using a variable to indicate that the critical section is in use. Real world analagies include "bathroom in use" signs, or a simple close (and perhaps lock) of the door.
  • This variable is tested before entering the critical section

Let's Try Again - Algorithm #2 (Incorrect)

Let's put what we learned in Algorithm #1 to work and try again. This time, we won't worry about turns. We'll juggle if the other process wants a turn. If it is not looking for the critical section, we won't have to forego its use. /* i is this process; j is the other process */

while (true) { while (state[j] == inside); /* is the other one inside? */

state[i] = inside; /* get in and flip state */

<<< critical section >>>

state[i] = outside; /* revert state */

<<< code outside critical section >>> }

This proposal has some nice features:

  • No blocking occurs unless the other process is inside of the critical section (progress criteria is satisfied).
  • To the extent allowed by the scheduler, there is a guarantee that both processes will eventually be able to enter the critical region.

But we still don't have a solution. To understand why this code is incorrect, we must remember two things:

  • The currently running process can be pre-emempted at any time -- leaving the current activity incomplete
  • Murphy's law will ensure that a context switch will occur at the most embarassing of all possible times. If there is an occasion for a context-switch to break our code, Mr. Murphy will find it.

Atomicity is the property of being executed as a single unit. This algorithm assumes that the test of (state[1] == inside) and the set of (state[0] = inside) are atomic. That is to say, this algorithm assumes that nothing can come in-between those two operations.

That assumption is inaccurate. A race-condition exists between testing and setting state. P 0 can be pre-empted between the two operations, by P 1. The result will be that P 1 will test state[0], find it false, and enter the critical section.

  1. P 0 loops in while

Both P 0 and P^1 loop forever. This is the livelock.

Algorithm #4: Peterson's Algorithm (Correct)

This time, let's try using Algorithm #3, but taking turns to break ties: /* i is this process; j is the other process */

while (true) { state[i] = interested; /* declare interest / turn = j; / be nice to other guy */

while (state[j] == interested && turn == j);

<<< critical section >>>

state[i] = notinterested; /* we’re done */

<<< code outside critical section >>> }

This code satisfies all three properties:

  • mutual exclusion
  • progress
  • bounded wait

It is interesting to note that this requires a formal proof to be really convincing. Proving erroneousness is easy: just give a counter-example. But proving correctness is much more difficult, since no number of examples is convincing. Instead, we'll focus on justifying the correctness with the same level of rigor that you might you during a discussion with your project partner.