Title: Mutual Exclusion with Busy Waiting
1Mutual Exclusion with Busy Waiting
- Disabling Interrupts
- Lock Variables
- Strict Alternation
- Petersons Solution
- TSL Instruction
2Strict Alternation
3- Proposed Solution 1
- while ( TRUE )
- while ( turn ! 0 ) / wait/
- critical_section( )
- turn 1
- noncritical_section ( )
-
4- Proposed Solution 2
- while ( TRUE )
- while ( turn !1 ) /wait/
- critical_section ( )
- turn 0
- noncritical_section ( )
5Petersons Solution
6- include prototypes.h
- define FALSE 0
- define TRUE 1
- define N 2 / number of processes /
- Â
- int turn
/ whose turn is it? / - int interested N / all values initially 0
(FALSE) / - Â
- void enter_region ( int process ) / process
who is entering (0 or 1) / -
- int other / number of the other process /
-
- other 1 process / the opposite of
process / - interested process TRUE / show that you
are interested / - turn process / set flag /
- while ( turn process interested other
TRUE ) / null statement / -
- Â void leave_region ( int process )
/ process who is leaving ( 0 or 1 ) / -
7TSL Instruction
8- enter_region
- tsl register, flag copy flag to register
and set flag to 1 - cmp register, 0 was flag zero?
- jnz enter_region if it was nonzero, lock
was set, so loop - ret return to caller critical region
entered - leave_region
- mov flag, 0 store a 0 in flag
- ret return to caller
9Producer-Consumer Problem
The producer-consumer problem illustrates the
need for synchronization in systems where many
processes share a resource. In the problem, two
processes share a fixed-size buffer. One process
produces information and puts it in the buffer,
while the other process consumes information from
the buffer. These processes do not take turns
accessing the buffer, they both work
concurrently. Herein lies the problem. What
happens if the producer tries to put an item into
a full buffer? What happens if the consumer tries
to take an item from an empty buffer? In order
to synchronize these processes, we will block the
producer when the buffer is full, and we will
block the consumer when the buffer is empty. So
the two processes, Producer and Consumer, should
work as follows
101) The producer must first create a new widget.
(2) Then, it checks to see if the buffer is full.
If it is, the producer will put itself to sleep
until the consumer wakes it up. A "wakeup" will
come if the consumer finds the buffer empty.(3)
Next, the producer puts the new widget in the
buffer. If the producer goes to sleep in step
(2), it will not wake up until the buffer is
empty, so the buffer will never overflow. (4)
Then, the producer checks to see if the buffer is
empty. If it is, the producer assumes that the
consumer is sleeping, an so it will wake the
consumer. Keep in mind that between any of these
steps, an interrupt might occur, allowing the
consumer to run.
11(1) The consumer checks to see if the buffer is
empty. If so, the consumer will put itself to
sleep until the producer wakes it up. A "wakeup"
will occur if the producer finds the buffer empty
after it puts an item into the buffer. (2) Then,
the consumer will remove a widget from the
buffer. The consumer will never try to remove a
widget from an empty buffer because it will not
wake up until the buffer is full.(3) If the
buffer was full before it removed the widget, the
consumer will wake the producer. (4) Finally, the
consumer will consume the widget. As was the case
with the producer, an interrupt could occur
between any of these steps, allowing the producer
to run.
12- include prototypes.h
- define N 100 / number of
slots in the buffer / - int count 0
- void producer (void)
- int item
- while ( TRUE ) /
repeat forever / - produce_item ( item )
/ generate next item / - if ( count N ) sleep ( ) /
if buffer is full, go to sleep / - enter_item ( item) / put item in
buffer / - count count 1 / increment
count of items in buffer / - if ( count 1) wakeup ( consumer ) /
was buffer empty? / -
-
13- void consumer ( void )
- int item
- while ( TRUE ) / repeat forever /
- if ( count 0) sleep ( ) / if
buffer is empty go to sleep / - remove_item ( item ) / take item out
of buffer / - count count 1 / decrement count of
items in buffer / - if ( count N 1) wakeup ( producer )
/ was buffer full? / - consume_item ( item ) /
print item / -
-
14Solving the Producer-Consumer Problem using
Semaphores
15- include prototypes.h
- define N 100 / number of slots in the buffer
/ - typedef int semaphore / semaphores are a
special kind of int / - Â
- semaphore mutex 1 / controls access to
critical region / - semaphore empty N / counts empty buffer
slots / - semaphore full 0 / counts full buffer slots
/ - Â
- void producer ( void )
-
- int item
- while ( TRUE ) / TRUE is the constant 1 /
- produce_item ( item ) / generate something
to put in buffer / - down ( empty ) / decrement empty count /
- down ( mutex ) / enter critical region /
- enter_item ( item ) / put new item in buffer
/ - up ( mutex ) / leave critical region /
- up ( full ) / increment count of full slots
/ -
16- void consumer ( void )
-
- int item
- while ( TRUE ) / infinite loop /
- down ( full ) / decrement full loop /
- down ( mutex ) / enter critical region /
- remove_item ( item ) / take item from
buffer / - up ( mutex ) / leave critical region /
- up ( empty ) / increment count of empty
slots / - consume_item ( item ) / do something with
the item / -
-
17Solving the Producer-Consumer Problem using
Event Counters
18- include prototypes.h
- define N 100 / number of slots in the
buffer / - typedef int event_counter / event_counters
are a special kind of int / - Â
- event_counter in 0 / counts items inserted
into buffer / - event_counter out 0 / counts items removed
from buffer / - Â
- void producer ( void )
-
- int item, sequence 0
- while ( TRUE ) / infinite loop /
- produce_item ( item ) / generate
something to put in buffer / - sequence sequence 1 / count items
produced so far / - await ( out, sequence N ) / wait until
there is room in buffer / - enter_item ( item ) / put item in slot (
sequence 1 ) N / - advance ( in ) / let consumer know
about another item / -
-
19- void consumer ( void )
-
- int item, sequence 0
- while ( TRUE ) / infinite loop /
- sequence sequence 1 / number of item to
remove from buffer / - await ( in, sequence ) / wait until
required item is present / - remove_item ( item ) / take item from
slot ( sequence 1 ) N / - advance ( out ) / let producer know that
item is gone / - consume_item ( item ) / do something with
the item / -
-
20Solving the Producer-Consumer Problem using
Monitors
21- monitor ProducerConsumer
- condition full, empty
- integer count
- procedure enter
- begin
- if count N then wait ( full )
- enter_item
- count count 1
- if count 1 then signal ( empty )
- end
- Â procedure remove
- begin
- if count 0 then wait ( empty )
- remove_item
- count count 1
- if count N 1 then signal ( full )
- end
22- Â
- procedure producer
- begin
- while true do
- begin
- produce_item
- ProducerConsumer.enter
- end
- end
- Â
- procedure consumer
- begin
- while true do
- begin
- ProducerConsumer.remove
- consume_item
- end
- end
23Message Passing
- This method of IPC uses two primitives SEND and
RECEIVE, - which, like semaphores and unlike monitors, are
system calls - rather than language constructs.
- send ( destination, message )
- and
- receive ( source, message )
- The former sends a message to a given
destination and the latter - receives a message from given source ( or from
any, if the receiver - does not care). If no message is available, the
receiver could block - until one arrives.
24Solving the Producer-Consumer Problem using
Message Passing
25- include prototypes.h
- define N 100 /number of slots in the buffer
/ - define MSIZE 4 / message size /
- typedef int message MSIZE
- Â
- void producer ( void )
-
- int item
- message m / message buffer /
- while ( TRUE )
- produce_item ( item ) / generate something
to put in buffer/ - receive ( consumer, m ) / wait for an empty
to arrive / - build_message ( m, item ) / construct a
message to send / - send ( consumer, m ) / send item to consumer
/ -
-
26- void consumer ( void )
-
- int item i
- message m
- for ( i 0, i lt N, i )
- send ( producer, m ) / send N empties /
- while ( TRUE)
- receive ( producer, m ) / get message
containing item / - extract_item ( m, item ) / take item out
of message / - send ( producer, m ) / send back empty
reply / - consumer_item ( item ) / do something with
item / -
-