P. 1
Lab Manual Os

# Lab Manual Os

|Views: 1,981|Likes:

Published by: Harshali Singh on Dec 24, 2010

### Availability:

Read on Scribd mobile: iPhone, iPad and Android.
See more
See less

05/23/2013

pdf

text

original

AIM OF THE EXPERIMENT:-

To Study and implement Dekker’s and Peterson’s Algorithm

THEORY:-

DEKKER'S ALGORITHM

• Dekker's algorithm is a concurrent programming algorithm for mutual exclusion
derived by the Dutch mathematician T. J. Dekker in 1964 that allows two threads
to share a single-use resource without conflict, using only shared memory for
communication.
• It avoids the strict alternation of a naive turn-taking algorithm, and was one of the
first mutual exclusion algorithms to be invented.
• If two processes attempt to enter a critical section at the same time, the algorithm
will allow only one process in, based on whose turn it is. If one process is already
in the critical section, the other process will Busy wait for the first process to exit.
• This is done by the use of two flags f0 and f1 which indicate an intention to enter
the critical section and a turn variable which indicates who has priority between
the two processes.

Pseudocode

f0 := false
f1 := false
turn := 0 // or 1

p0: p1:
f0 := true f1 := true
while f1 { while f0 {
if turn ≠ 0 { if turn ≠ 1 {
f0 := false f1 := false
while turn ≠ 0 { while turn ≠ 1 {
} }
f0 := true f1 := true
} }
} }

// critical section // critical section
... ...
// remainder section // remainder section
turn := 1 turn := 0
f0 := false f1 := false

Processes indicate an intention to enter the critical section which is tested by the outer
while loop.
If the other process has not flagged intent, the critical section can be entered safely
irrespective of the current turn.
Mutual exclusion will still be guaranteed as neither process can become critical before
setting their flag (implying at least one process will enter the while loop). T
his also guarantees progress as waiting will not occur on a process which has withdrawn
intent to become critical.
Alternatively, if the other process's variable was set the while loop is entered and the turn
variable will establish who is permitted to become critical.
Processes without priority will withdraw their intention to enter the critical section until
they are given priority again (the inner while loop).
Processes with priority will break from the while loop and enter their critical section.

Dekker's algorithm guarantees mutual exclusion, freedom from deadlock, and freedom
from starvation. Let us see why the last property holds. Suppose p0 is stuck inside the
"while f1" loop forever. There is freedom from deadlock, so eventually p1 will proceed to
its critical section and set turn = 0 (and the value of turn will remain unchanged as long as
p0 doesn't progress). Eventually p0 will break out of the inner "while turn ≠ 0" loop (if it
was ever stuck on it). After that it will set f0 := true and settle down to waiting for f1 to
become false (since turn = 0, it will never do the actions in the while loop). The next time
p1 tries to enter its critical section, it will be forced to execute the actions in its "while f0"
loop. In particular, it will eventually set f1 = false and get stuck in the "while turn ≠ 1"
loop (since turn remains 0). The next time control passes to p0, it will exit the "while f1"
loop and enter its critical section.

If the algorithm were modified by performing the actions in the "while f1" loop without
checking if turn = 0, then there is a possibility of starvation. Thus all the steps in the
algorithm are necessary.

One advantage of this algorithm is that it doesn't require special Test-and-set (atomic
read/modify/write) instructions and is therefore highly portable between languages and
machine architectures. One disadvantage is that it is limited to two processes and makes
use of Busy waiting instead of process suspension. (The use of busy waiting suggests that
processes should spend a minimum of time inside the critical section.)

Modern operating systems provide mutual exclusion primitives that are more general and
flexible than Dekker's algorithm. However, it should be noted that in the absence of
actual contention between the two processes, the entry and exit from critical section is
extremely efficient when Dekker's algorithm is used.

Many modern CPUs execute their instructions in an out-of-order fashion. This algorithm
won't work on SMP machines equipped with these CPUs without the use of memory
barriers.

Additionally, many optimizing compilers can perform transformations that will cause this
algorithm to fail regardless of the platform. In many languages, it is legal for a compiler
to detect that the flag variables f0 and f1 are never accessed in the loop. It can then
remove the writes to those variables from the loop, using a process called Loop-invariant
code motion. It would also be possible for many compilers to detect that the turn variable
is never modified by the inner loop, and perform a similar transformation, resulting in a
potential infinite loop. If either of these transformations is performed, the algorithm will
fail, regardless of architecture.

To alleviate this problem, volatile variables should be marked as modifiable outside the
scope of the currently executing context. For example, in Java, one would annotate these
variables as 'volatile'. Note however that the C/C++ "volatile" attribute only guarantees
that the compiler generates code with the proper ordering; it does not include the
necessary memory barriers to guarantee in-order execution of that code.

PETERSON'S ALGORITHM

Peterson's algorithm is a concurrent programming algorithm for mutual exclusion that
allows two processes to share a single-use resource without conflict, using only shared
memory for communication.
It was formulated by Gary Peterson in 1981 at the University of Rochester.
While Peterson's original formulation worked with only two processes, the algorithm can
be generalised for more than two, as discussed in "Operating Systems Review, January
1990 ('Proof of a Mutual Exclusion Algorithm', M Hofri)".

The algorithm

flag[0] = 0
flag[1] = 0
turn = 0

P0: flag[0] = 1 P1: flag[1] = 1
turn = 1 turn = 0
while( flag[1] && turn == 1 ); while( flag[0] && turn == 0 );
// do nothing // do nothing
// critical section // critical section
... ...
// end of critical section // end of critical section
flag[0] = 0 flag[1] = 0

The algorithm uses two variables, flag and turn. A flag value of 1 indicates that the
process wants to enter the critical section. The variable turn holds the ID of the process

whose turn it is. Entrance to the critical section is granted for process P0 if P1 does not
want to enter its critical section or if P1 has given priority to P0 by setting turn to 0.

The algorithm does not satisfy completely the three essential criteria of mutual exclusion:

Mutual exclusion

P0 and P1 can never be in the critical section at the same time: If P0 is in its critical
section, then flag[0] is 1 and either flag[1] is 0 or turn is 0. In both cases, P1 cannot be in
its critical section.

Progress requirement

This criteria says that no process which is not in a critical section is allowed to block a
process which wants to enter the critical section.There is not strict alternating between P0
and P1.

However, there is the possibility that this requirement is not met:
1. P[0] sets Flag[0]=1 and turn=1
2. context switch
3. P[1] sets Flag[1]=1
4. context switch
5. P[0] enters its critical section
6. P[0] leaves its critical section
7. now if P[0] wants to enter its critical section again, it has to wait until P[1] sets turn=0,
even though there is currently no process in the critical section

Bounded waiting

A process will not wait longer than one turn for entrance to the critical section: After
giving priority to the other process, this process will run to completion and set its flag to
0, thereby allowing the other process to enter the critical section.

When working at the hardware level, Peterson's algorithm is typically not needed to
achieve atomic access. Some processors have special instructions, like test-and-set or
compare-and-swap that, by locking the memory bus, can be used to provide mutual
exclusion in SMP systems.

Most modern CPUs reorder memory accesses to improve execution efficiency. Such
processors invariably give some way to force ordering in a stream of memory accesses,
typically through a memory barrier instruction. Implementation of Peterson's and related
algorithms on processors which reorder memory accesses generally require use of such
operations to work correctly to keep sequential operations from happening in an incorrect
order. Note that reordering of memory accesses can happen even on processors that don't
reorder instructions (such as the PowerPC processor on the Xbox 360).

Most such CPU's also have some sort of guaranteed atomic operation, such as XCHG on
x86 processors and Load-Link/Store-Conditional on Alpha, MIPS, PowerPC, and other

architectures. These instructions are intended to provide a way to build synchronization
primitives more efficiently than can be done with pure shared memory approaches.

REFFERENCE BOOK:- William Stallings,”Operating Systems”, Fourth
Edition, Pearson Education

REQUIREMENT:- TURBO C++ / JAVA

scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->