Presentation is loading. Please wait.

Presentation is loading. Please wait.

Jonathan Walpole Computer Science Portland State University

Similar presentations


Presentation on theme: "Jonathan Walpole Computer Science Portland State University"— Presentation transcript:

1 Jonathan Walpole Computer Science Portland State University
CS 333 Introduction to Operating Systems Class 6 – Monitors and Message Passing Jonathan Walpole Computer Science Portland State University

2 Monitors It is difficult to produce correct programs using semaphores
correct ordering of up and down operations is tricky! Can we get the compiler to generate the correct semaphore code for us? what are suitable higher level abstractions for synchronization?

3 Monitors Collect related shared objects together in a monitor
Characteristics Local data variables are accessible only via the monitor’s procedures Processes enter the monitor by invoking one of its procedures Only one process may execute within the monitor at a given time Condition variables (cv) Wait(cv) – block on condition Signal(cv) – wake up process waiting on cv

4 Monitor structures shared data monitor entry queue condition queues x
initialization code monitor operations y x shared data condition queues monitor entry queue

5 Monitor example for mutual exclusion
process Producer begin loop <produce char “c”> BoundedBuffer.deposit(c) end loop end Producer monitor: BoundedBuffer var buffer : ...; nextIn, nextOut :... ; entry deposit(c: char) begin ... end entry remove(var c: char) end BoundedBuffer process Consumer begin loop BoundedBuffer.remove(c) <consume char “c”> end loop end Consumer

6 Condition variables Condition variables allow processes to synchronize based on some state of the monitor variables For example: Buffer_full in the producer/consumer Operations wait(cv) and signal(cv) allow synchronization within a monitor Only one processor active at one time what happens on a signal from A to B? A waits for B to leave monitor, or waits for another condition B waits for A to leave monitor, or waits for another condition … and what happens on wait?

7 Monitor example monitor : BoundedBuffer
var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then if (fullCount = n) then wait(notFull) wait(notEmpty) end if end if buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

8 Condition synchronization semantics
Signaling and signaled processes can not both run What if signaling process continues to run and signals other condition variable? What if signaled process continues to run and signals other condition variables? What order should processes run? How do you avoid deadlock?

9 Condition synchronization semantics
Hoare Semantics On signal, allow signalled process to run; upon its exit from the monitor, signaller process continues Stonger guarantees Easier to prove correctness Mesa Semantics (Xerox PARC) Signal is merely a “hint” Requires process to check that condition is ok to continue upon receipt of signal

10 Producer consumer with message passing

11 Barriers Use of a barrier processes approaching a barrier
all processes but one blocked at barrier last process arrives, all are let through

12 Summary Process synchronization topics Reading Semaphores IPC problems
Monitors Reading

13 Monitors It is difficult to produce correct programs using semaphores
correct ordering of up and down is tricky! avoiding deadlock is tricky! boundary conditions are tricky! Can we get the compiler to generate the correct semaphore code for us? what are suitable higher level abstractions for synchronization?

14 Monitors Collect related shared objects together in a monitor
Encapsulation and mutual exclusion Local data variables are accessible only via the monitor’s procedures Processes enter the monitor by invoking one of its procedures Only one process may execute within the monitor at a given time Condition variables (cv) Wait(cv) – process blocked (queued) until condition holds Signal(cv) – signals the condition and unblocks (dequeues) a process

15 Monitor structures shared data monitor entry queue condition queues x
initialization code monitor operations y x shared data condition queues monitor entry queue

16 Monitor example for mutual exclusion
process Producer begin loop <produce char “c”> BoundedBuffer.deposit(c) end loop end Producer monitor: BoundedBuffer var buffer : ...; nextIn, nextOut :... ; entry deposit(c: char) begin ... end entry remove(var c: char) end BoundedBuffer process Consumer begin loop BoundedBuffer.remove(c) <consume char “c”> end loop end Consumer

17 Monitor example with condition variables
monitor : BoundedBuffer var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then if (fullCount = n) then wait(notFull) wait(notEmpty) end if end if buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

18 Monitor design choices
Condition variables introduce a problem for mutual exclusion only one process active in the monitor at a time, so what to do when a process is unblocked on signal? must not block holding the mutex, so what to do when a process blocks on wait? Should signals be stored/remembered? signals are not stored if signal occurs before wait, signal is lost! Should condition variables count?

19 Monitor design choices
Choices when A signals a condition that unblocks B A waits for B to exit the monitor or blocks again B waits for A to exit the monitor or block Signal causes A to immediately exit the monitor or block (on what condition?) Choices when A signals a condition that unblocks B & C B is unblocked, but C remains blocked C is unblocked, but B remains blocked Choices when A calls wait and blocks a new external process is allowed to enter but which one?

20 Common monitor semantics
Hoare semantics On signal, allow signaled process to run; upon its exit from the monitor, signaler process continues Brinch Hansen semantics signaler must immediately exit following signal

21 Message Passing Interprocess communication
via shared memory across machine boundaries Message passing can be used locally or remotely for synchronization or general communication processes use send and receive primitives receive can block like wait send unblocks a process blocked on receive (like signal unblocking a waiting process)

22 Producer consumer with message passing

23 Design Choices for Message Passing
Mailboxes system maintains a buffer of sent, but not yet received, messages Rendezvous sender and receiver must be active at the same time receive must be blocked before send occurs kernel does no buffering when does the send return?

24 Barriers Use of a barrier processes approaching a barrier
all processes but one blocked at barrier last process arrives, all are let through

25 Monitors (1) Example of a monitor

26 Monitors (2) Outline of producer-consumer problem with monitors
only one monitor procedure active at one time buffer has N slots

27 Solution to producer-consumer problem in Java (part 1)
Monitors (3) Solution to producer-consumer problem in Java (part 1)

28 Solution to producer-consumer problem in Java (part 2)
Monitors (4) Solution to producer-consumer problem in Java (part 2)

29 Semantics of monitors What is the strongest statement we can make about the state of the monitor after a waiter wakes up? entry deposit(c:char) entry remove(var c: char) begin begin if (fullCount = n) then : : wait(notFull) c := buffer[nextOut] fullCount := fullCount-1 end if signal(notFull) end deposit end remove

30 Synchronization problems with Mesa
P P P3 /* fullCount=n */ if (fullCount==n) wait(notFull); remove() ... fullCount--; signal(notFull); /* exit monitor */ /* fullCount=n-1*/ deposit() fullCount++;

31 Mesa semantics monitor : BoundedBuffer
var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 fullCount : 0..n := 0 notEmpty, notFull : condition entry deposit(c:char) entry remove(var c: char) begin begin while (fullCount = n) then while (fullCount = n) then wait(notFull) wait(notEmpty) end while end while buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n fullCount := fullCount fullCount := fullCount-1 signal(notEmpty) signal(notFull) end deposit end remove end BoundedBuffer

32 Introduction to Operating Systems Chapter 2 (partial) Monitors, Reentrant Code, Message Passing, and Barriers

33 It is difficult to produce correct programs
Introduction It is difficult to produce correct programs using locks and semaphores!!! Correct ordering of Up and Down operations is tricky! Desirable: Language / compiler support for IPC What are suitable high-level abstractions for synchronization?

34 Monitors Collect related, shared objects together in a “monitor”
Characteristics: • Local data variables are accessible only via the monitor’s procedures/methods • Threads enter the monitor by invoking one of its procedures/methods • Only one thread may execute within the monitor at a given time “Condition Variables” (cv) Wait(cv) – block on condition Signal(cv) – wake up one thread waiting on cv

35 Monitor structures shared data monitor entry queue x
condition variables y “entry” methods local methods initialization code

36 (Each has an associated list of waiting threads)
Monitor structures shared data monitor entry queue x condition variables y Local to monitor (Each has an associated list of waiting threads) List of threads waiting to enter the monitor “entry” methods Can be called from outside the monitor. Only one active at any moment. local methods initialization code

37 Example: The “Bounded-Buffer” Monitor
monitor BoundedBuffer var buffer: ... nextIn, nextOut :... entry deposit(c: char) begin ... end entry remove() return c endMonitor Producer Thread: while true -- Produce char “c” BoundedBuffer.deposit(c) endWhile Consumer Thread: while true c = BoundedBuffer.remove() -- Consume char “c” endWhile

38 The “BoundedBuffer” Monitor
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() endMonitor nextOut nextIn A B C D N-1 cntFull=4

39 Code for the “deposit” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) if cntFull == N notFull.Wait() endIf buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor nextOut nextIn A B C D N-1 cntFull=4

40 Code for the “remove” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() if cntFull == 0 notEmpty.Wait() endIf c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor nextOut nextIn A B C D N-1 cntFull=4

41 Condition Variables Examples from producer/consumer:
“Condition variables allow processes to synchronize based on some state of the monitor variables.” Examples from producer/consumer: “Buffer-Full” condition “Buffer-Empty” condition Operations Wait(cv) and Signal(cv) allow synchronization within the monitor When a producer thread adds an element... A consumer may be sleeping Need to wake the consumer... Signal

42 Condition synchronization semantics
“Only one thread can be executing in the monitor at any one time.” Scenario: Thread A is executing in the monitor. Thread A does a Signal, waking up thread B. What happens now? Signaling and signaled threads can not both run!

43 Condition synchronization semantics
Option 1: Hoare Semantics What happens when a Signal is performed? The signaling thread (A) is suspended. The signaled thread (B) wakes up and runs immediately. B can assume the condition is now true/satisfied • Stronger guarantees • Easier to prove correctness When B leaves monitor, then A can run. After B leaves monitor... A might resume execution immediately ... or maybe another thread (C) will slip in!

44 Condition synchronization semantics
Option 2: MESA Semantics (Xerox PARC) What happens when a Signal is performed? • The signaling thread (A) continues. • The signaled thread (B) waits. When A leaves monitor, then B runs. Issue: What happens when B waits? When A leaves the monitor, can some other thread (C) slip in first? (Can some other thread (C) run after A signals, but before B runs?) • A signal is more like a hint. • Requires B to recheck the state of the monitor variables to see if it can proceed or must wait some more.

45 Code for the “deposit” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) if cntFull == N notFull.Wait() endIf buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor Hoare Semantics

46 Code for the “deposit” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) while cntFull == N notFull.Wait() endWhile buffer[nextIn] = c nextIn = (nextIn+1) mod N cntFull = cntFull + 1 notEmpty.Signal() endEntry entry remove() ... endMonitor MESA Semantics

47 Code for the “remove” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() if cntFull == 0 notEmpty.Wait() endIf c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor Hoare Semantics

48 Code for the “remove” entry routine
monitor BoundedBuffer var buffer: array[n] of char nextIn, nextOut: int = 0 cntFull: int = 0 notEmpty: Condition notFull: Condition entry deposit(c: char) ... entry remove() while cntFull == 0 notEmpty.Wait() endWhile c = buffer[nextOut] nextOut = (nextOut+1) mod N cntFull = cntFull - 1 notFull.Signal() endEntry endMonitor MESA Semantics

49 “Hoare Semantics” What happens when a Signal is performed?
The signaling thread (A) is suspended. The signaled thread (B) wakes up and runs immediately. B can assume the condition is now true/satisfied From the original Hoare Paper: “No other thread can intervene [and enter the monitor] between the signal and the continuation of exactly one waiting thread.” “If more than one thread is waiting on a condition, we postulate that the signal operation will reactivate the longest waiting thread. This gives a simple neutral queuing discipline which ensures that every waiting thread will eventually get its turn.”

50 Implementing Hoare Semantics
Implementation? Thread A holds the monitor lock. Thread A issues a Signal. Thread B will be moved back to the ready queue. Thread A must be suspended... Possession of the monitor lock must be passed from A to B. When B finishes and gets ready to return... The lock can be released. Thread A must re-aquire the lock. Perhaps A is blocked, waiting to re-aquire the lock.

51 Implementing Hoare Semantics
Problem: “Possession of the monitor lock must be passed from A to B.” Each mutex remembers which thread holds it. My version of Mutex: Any attempt by thread B to release the monitor lock will cause an error message. Your Solution: Modify Mutex to eliminate the check?

52 Implementing Hoare Semantics
Recommendation: Do not modify the methods that I am supplying. (Future code I release will use them) Create new classes: MonitorLock -- similar to Mutex HoareCondition -- similar to Condition

53 Implementing Hoare Semantics
Scenario: Thread B does a Wait. Thread A executes a Signal. Thread B wakes up, executes, and returns. Last thing B does: Unlock the monitor lock. Problem: What happens next? Thread A is waiting for B to finish. It is trying to reaquire the monitor lock. What about thread C? Also trying to acquire lock, and waiting longer? Hoare: “A must get the lock after B.” C must continue to wait.

54 Implementing Hoare Semantics
Things are getting complex. Simply ending monitor entry methods with monLock.Unlock() will no longer work. Implementation Ideas: Need a special thing called a “MonitorLock”. Consider a thread like A to be “urgent”. Thread C is not “urgent”. Consider 2 wait lists associated with each MonitorLock • UrgentlyWaitingThreads • NonurgentlyWaitingThreads Want to wake up urgent threads first, if any.

55 Brinch-Hansen Semantics
Hoare Semantics On signal, allow signaled process to run. Upon its exit from the monitor, signaler process continues. Brinch-Hansen Semantics Signaler must immediately exit following any invocation of signal. (Implementation of is easier.)

56 Reentrant Code A function/method is said to be “reentrant” if...
“A function that has been invoked may be invoked again before the first invocation has returned, and will still work correctly.” Recursive routines are reentrant. In the context of multi-programming... A reentrant function can be executed simultaneously by more than one thread, with no ill effects.

57 Reentrant Code Consider this function... var count: int = 0
function GetUnique () returns int count = count + 1 return count endFunction What if it is executed by different threads?

58 Reentrant Code Consider this function... var count: int = 0
function GetUnique () returns int count = count + 1 return count endFunction What if it is executed by different threads? The results may be incorrect! This routine is not reentrant!

59 Reentrant Code When is code “reentrant”? Assumption:
A multi-threaded program Some variables are “local” -- to the function/method/routine “global” -- sometimes called “static” Access to local variables? A new stack frame is created for each invocation. Access to global variables? Must use synchronization!

60 Making this Function Reentrant
var count: int = 0 myLock: Mutex function GetUnique () returns int var i: int myLock.Lock() count = count + 1 i = count myLock.Unlock() return i endFunction

61 Message Passing Interprocess Communication
• via shared memory • across machine boundaries Message passing can be used locally or remotely Can be used for... synchronization, or general communication Processes use Send and Receive primitives • Receive can block (like Waiting on a Semaphore) • Send unblocks a process blocked on Receive (Just as a Signal unblocks a Waiting process)

62 Producer-Consumer with Message Passing
Idea: After producing, the producer sends the data to consumer in a message. The system buffers messages. The producer can out-run the consumer. The messages will be kept in order. After consuming the data, the consumer sends back an “empty” message. A fixed number of messages (N=100) The messages circulate back and forth.

63 Producer-Consumer with Message Passing
const N = Size of message buffer var em: char for i = 1 to N Get things started by Send (producer, &em) sending N empty messages endFor thread consumer var c, em: char while true Receive(producer, &c) -- Wait for a char Send(producer, &em) Send empty message back // Consume char... endWhile end

64 Producer-Consumer with Message Passing
thread producer var c, em: char while true // Produce char c... Receive(consumer, &em) -- Wait for an empty msg Send(consumer, &c) Send c to consumer endWhile end

65 Design Choices for Message Passing
Option 1: “Mailboxes” System maintains a buffer of sent, but not yet received, messages. Must specify the size of the mailbox ahead of time. Sender will be blocked if buffer is full. Receiver will be blocked if the buffer is empty.

66 Design Choices for Message Passing
Option 1: “Mailboxes” System maintains a buffer of sent, but not yet received, messages. Must specify the size of the mailbox ahead of time. Sender will be blocked if buffer is full. Receiver will be blocked if the buffer is empty. Option 2: The kernel does no buffering If Send happens first, the sending thread blocks. If Receiver happens first, the receiving thread blocks. “Rendezvous” Both threads are ready for the transfer. The data is copied / transmitted Both threads are then allowed to proceed.

67 Barriers • Processes approaching a barrier
• All processes but one blocked at barrier • Last process arrives; all are let through

68 Monitors: An Operating System Structuring Concept
Paper by: C. A. R. Hoare Presented by: Sabrina Brick chance to read paper? accomplished famous for quicksort hoare logic among other things look him up!

69 Why monitors? Concurrency has always been an OS issue
Resource allocation is necessary among competing processes Timer interrupts Existing synchronization mechanisms (semaphores, locks) are subject to hard-to-find, subtle bugs. the motivation for this research? follows our discussion on threads, concurrent programming last week. Why was Tony Hoare looking at concurrency in the early 1970's? It's not like there were multi-threaded user applications or multiprocessors then.

70 What is a monitor? A collection of data and procedures
Mutual exclusion allows controlled acquisition and release of critical resources single anonymous lock automatically acquired and released at entry and exit Data encapsulation monitor procedures are “entry points” for accessing data The basics of a monitor organized as a collection of data along with the associated procedures monitors provide a method for mutual exclusion ONLY ALLOWS CONTROLLED ACCESS to whatever critical resources it may be protecting has a single lock Data encapsulation...like a class

71 Monitors: a language construct
Monitors are a programming language construct anonymous lock issues handled by compiler and OS detection of invalid accesses to critical sections happens at compile time process of detection can be automated by compiler by scanning the text of the program

72 An Abstract Monitor name: monitor …local declarations
…initialize local data proc1 (…parameters) …statement list proc2 (…parameters) proc3 (…parameters)

73 Rules to Follow with Monitors
Any process can call a monitor procedure at any time But only one process can be inside a monitor at any time (mutual exclusion) No process can directly access a monitor’s local variables (data encapsulation) A monitor may only access its local variables Why? Race conditions could occur! “Chaos will ensue”!

74 Enforcing the Rules “wait” operation “signal” operation
current process is put to sleep “signal” operation wakes up a sleeping process condition variables May have different reasons for “waiting” or “signaling” Processes waiting on a particular condition enter its queue Here are the mechanisms that enforce the rules we just listed. These are all very similar to the ideas we discussed last week with threads.

75 Sabrina’s Car: a running example
monitor declaration local variables / initializations procedure car: monitor occupied: Boolean; occupied := false; nonOccupied: condition; procedure enterCar() if occupied then nonOccupied.wait; occupied = true; procedure exitCar() occupied = false; nonOccupied.signal; What possible problem exists? So here's my car as an example! Because the only seat that's really important is the driver's seat...we can represent this situation as a very basic monitor. pseudocode...but basic structure is here notice the various parts that are labeled...

76 The Possible Problem As discussed in Birrell’s paper (last class):
First process: Completes it’s work with critical section Signals a process waiting on “nonOccupied” Starts to release the monitor when… Second process: Is awakened by first process Tries an “entry point” into the monitor First process isn’t finished releasing it so it blocks again! This can’t happen with Hoare’s approach: Signal must be the last operation in a monitor. Signal and monitor exit are a combined operation. atmoic instruction nothing can interrupt from when the signal is sent to when the process exits the monitor. This is not actually the way that most monitors are implemented in real languages, so this problem does exist

77 Multiple Conditions Sometimes it is necessary to be able to wait on multiple things Can be implemented with multiple conditions Example: 2 reasons to enter car drive (empties tank) fill up car Two reasons to wait: Going to gas station but tank is already full Going to drive but tank is (almost) empty producer / consumer problem

78 Sabrina’s Car: a running example
car: monitor emptyTank, fullTank: condition; tank: stack; tank := stack of 10 gallons; //10 gallon tank //filled in increments of a gallon procedure driveCar() if tank.isAlmostEmpty then fullTank.wait; tank.pop(); //consume gas in increments of a gallon emptyTank.signal; procedure fillCar() if tank.isFull then emptyTank.wait; tank.push(gallons.pop); //assume gas station “stack” has infinite supply fullTank.signal;

79 Condition Queue Might want to check if any process is waiting on a condition The “condition queue” returns true if a process is waiting on a condition Example: filling the tank only if someone is waiting to drive the car.

80 Sabrina’s Car: a running example
car: monitor emtpyTank, fullTank: condition; tank: stack; tank := stack of 10 gallons; //10 gallon tank //filled in increments of a gallon procedure driveCar() if tank.isAlmostEmpty then fullTank.wait; tank.pop(); //consume gas in increments of a gallon emptyTank.signal; procedure fillCar() if tank.isFull then emptyTank.wait; if fullTank.queue //returns true if a process is waiting on fullTank tank.push(gallons.pop); //assume gas station “stack” has infinite supply fullTank.signal;

81 Priority: Scheduled Waits
A waiting process is given a number The process with the lowest number gets woken up first Example: People who want to drive my car are prioritized: Highest: Me! Medium: Family Lowest: Friends/Others priority inversion where the lowest number is given to the process with the highest priority

82 Sabrina’s Car: a running example
car: monitor emtpyTank, fullTank: condition; tank: stack; tank := stack of 10 gallons; //10 gallon tank //filled in increments of a gallon procedure driveCar(p: person) if tank.isAlmostEmpty then if p.isSabrina then fullTank.wait(1); if p.isFamily then fullTank.wait(2); if p.isFriendorOther then fullTank.wait(3); tank.pop(); //consume gas in increments of a gallon emptyTank.signal; procedure fillCar() if tank.isFull then emptyTank.wait; if fullTank.queue tank.push(gallons.pop); //assume gas station has infinite supply fullTank.signal;

83 Other issues Power of Monitors Proof rules
Monitor->semaphore and vice versa Proof rules I {b.wait} I&B I&B {b.signal} I I : the invariant B : the condition that a process waiting on b wants to be true before its woken up b : the condition variable hoare logic invariant? We talked about this last class... a condition or set of conditions that MUST be true when?

84 Lots of Great Examples OS Examples: Bounded Buffer Alarm clock
Disk head scheduler Reader/writer Buffer Allocation

85 Monitors and Granularity
Monitors are designed for course-grained locking Example: locking an entire data structure rather than its individual components. Is this an appropriate solution for all cases? Why or why not? What problems arise when the granularity is too coarse? What about the opposite case?

86 Monitors: implementation issues
Disabling Interrupts car: monitor occupied: Boolean; occupied := false; nonOccupied: condition; procedure enterCar() //disableInterrupts(); if occupied then nonOccupied.wait; occupied = true; //enableInterrupts(); procedure exitCar() occupied = false; nonOccupied.signal; “Yellow code” inserted into binary by compiler Which is the better approach? Why? Using a lock car: monitor occupied: Boolean; occupied := false; nonOccupied: condition; //lock1: lock; procedure enterCar() //lock1.acquire(); if occupied then nonOccupied.wait; occupied = true; //lock1.release(); procedure exitCar() occupied = false; nonOccupied.signal; //lock1.acquire() //disableInterrupts(); //lockVar = 1; //enableInterrupts(); What are some possibilities for implementation?

87 What problems do monitors solve?
Mutual exclusion Encapsulation of data Compiler can automatically scan program text for some types of synchronization bugs Synchronization of shared data access simplified vs. semaphores and locks Good for problems that require course granularity Invariants are guaranteed after waits Theoretically, a process that waits on a condition doesn’t have to retest the condition when it is awakened.

88 What remains problematic?
No way to check dynamically allocated shared data Signals are as error prone as with other synchronization mechanisms Deadlock can still happen in monitor code Programmer can still screw up Monitors are available in very few languages

89 Conclusions Monitors are a synchronization mechanism
A higher level, easier to use abstraction, better encapsulation than semaphores, etc. Monitors still suffer from various problems Let’s take a look at working model that addresses some of those issues! (Suzanne’s presentation)

90 References Jon Walpole
“Monitors: An Operating Systems Structuring Concept” Hoare. Modern Operating Systems, Second Edition. Tannenbaum, pp Emerson Murphy-Hill presentation from CS533, Winter 2005

91 Experience with Processes and Monitors in Mesa
B. W. Lampson Xerox Palo Alto Research Center D. D. Redell Xerox Business Systems Communications of the ACM v.23, n.2, Feb.1980, pp

92 Design Goals Local concurrent programming Global resource sharing
Replacing interrupts

93 Concurrent Programming using Monitors in Mesa
Interactions with process creation and destruction How to define WAIT Priority scheduling Semantics of nested monitor calls Handling timeouts, aborts, and other exceptions Monitoring large numbers of small objects

94 SU signal & urgent wait Hoare’74
Signaling in Monitors J. H. Howard 2nd Intl. Conf. of Software Engr, Oct.1976 SU signal & urgent wait Hoare’74 signaler to “urgent” queue & resumes after signaled process runs SR signal & return Brinch Hansen’75 return from monitor immediately after signaling Concurrent PASCAL SW signal & wait Howard’76 signaled immediate access signaler to monitor’s entry queue SC signal & continue signaler’s view of monitor state not corrupted requires explicit recording of signals pending Problems SU & SW: signalers might wait & restart unnecessarily SR simplest but may be inadequate & SC complex

95 Signaling thread suspends on urgent
Excerpt of Tanenbaum’s Example of Hoare Semantic Monitor ProducerConsumer condition full, empty; integer count; procedure insert (item; integer); begin Modification for Mesa Semantic if count = N then wait (full); while not count = N do wait (full) insert_item (item); count := count + 1; if count = 1 then signal (empty); end; Hoare semantic Mesa semantic Signaling thread suspends on urgent Signaled thread wakes & runs immediately First thread regains possession of monitor when second completes Signaling thread continues Signaled thread rechecks condition because order not guaranteed Avoid context switch

96 Allocate: ENTRY PROCEDURE [size: INTEGER
StorageAllocator: MONITOR = BEGIN availableStorage: INTEGER: moreAvailable: CONDITION: Allocate: ENTRY PROCEDURE [size: INTEGER RETURNS [p: POINTER] = BEGIN UNTIL availableStorage >= size DO WAIT moreAvailable ENDLOOP; p <- <remove chunk of size words & update availableStorage> END; Free: ENTRY PROCEDURE [p: POINTER, Size: INTEGER] = BEGIN <put back chunk of size words & update availableStorage>; NOTIFY moreAvailable END; Expand:PUBLIC PROCEDURE [pOld: POINTER, size: INTEGER] RETURNS [pNew: POINTER] = BEGIN pNew <- Allocate[size]; <copy contents from old block to new block>; Free[pOld] END; END.

97 Mutual exclusion Asynchronous processes must not Allocate and Free simultaneously → use entry procedures Monitor lock not needed during copy in Expand → use external procedure Structure the monitor computations only when lock is already held → use internal procedure

98 Define WAIT If caller waits in entry procedure, it releases the lock
If wait in internal procedure, the lock is released If monitor calls procedure outside the monitor, the lock is not released

99 Invariant Always true, except when process is executing in the monitor
On entry, invariant assumed to hold Invariant established before control leaves monitor Monitor procedure must establish invariant before WAIT Consider exception handler called from entry procedure

100 Causes of Pair-wise Deadlock
2 processes WAIT in a single monitor Cyclic calling between 2 monitors → impose a partial order Two level data abstraction

101 Two level data abstraction
Example: Monitor M calls N and waits for C requires process to enter N through M to set C → DEADLOCK Divide M into monitor M’ and interface O to call N

102 Monitored Objects Collection of shared data objects
Multiple instances of monitor Duplication of program linking and code swapping Monitored record To access a file, pass as parameter to effectively create a separate monitor for each object (read-only, no aliasing)

103 Abandon computation UNWIND exception to allow clean-up by any active procedure If procedure to be abandoned is an entry procedure, must restore invariant and release lock Programmer provides handler or experiences deadlock Compare to Java exception handling

104 Condition variables Process establishes a condition for which another process waits NOTIFY is a hint that waiting process will resume and reacquire the monitor lock No guarantee about another process interceding Waiter must reevaluate when it resumes Mesa WHILE NOT <OK to proceed> DO WAIT c ENDLOOP Hoare IF NOT <OK to proceed> THEN WAIT c

105 Verification rules Simpler and more localized
Invariant established before return from entry procedure or a WAIT Invariant assumed at start of entry procedure and just after a WAIT Waiter explicitly tests Notify condition may be more general (low cost to wake a process)

106 NOTIFY alternatives Timeout with interval Abort Broadcast
I/O device communication device cannot wait on monitor lock notify condition variable to wake interrupt handler

107 Priorities Ordering implied by assignment of priorities can be subverted by monitors Associate with each monitor the priority of the highest priority process that ever enters the monitor (Modula disables interrupts, but this fails with page fault.)

108 Example of subverted priority
Process P1 enters monitor M, P2 preempts, P3 preempts P3 tries to enter monitor and waits for lock P1 enter M P2 preempt P1 P3 preempt P2 P2 runs again, effectively keeps P3 from running, undermining the priorities.

109 Process states (pcbs) in queues sorted by priority
Processor Process states (pcbs) in queues sorted by priority Ready queue Monitor lock queue Condition variable queue Fault queue Queue cell process state process state process state ---- head tail

110 Implementation Compiler – flags errors
WAIT in external procedure direct call from external to internal procedure Runtime – process creation and destruction Machine – process scheduling and monitor entry/exit

111 Performance

112 Validation of Mesa Semantic
Operating system Interrupt handling lack of mutual exclusion Interaction of concurrency and exception Database Single monitor and single condition variable Array of representative states Network communication Router monitor Network driver monitor

113 Closing comparison

114 Implementation

115 Should signal be the last operation of a monitor procedure?
Monitor – low level mechanism Starvation addressed by high level scheduling Simpler & localized verification rules Signaled process checks specific condition More general condition for notify Questions Should signal be the last operation of a monitor procedure? How is exception handling addressed?


Download ppt "Jonathan Walpole Computer Science Portland State University"

Similar presentations


Ads by Google