CS533 Concepts of Operating Systems Class 3 Monitors
CS533 - Concepts of Operating Systems 2 But first … … catch up from last time o synchronization errors and Eraser
CS533 - Concepts of Operating Systems 3 Enforcing mutual exclusion Assumptions: o Every thread sets the lock before accessing shared data! o Every thread releases the lock after it is done! Only works if you follow these programming conventions all the time! Thread 1 Thread 2 Thread 3 Lock Lock A = 2 A = A+1 A = A*B Unlock Unlock
CS533 - Concepts of Operating Systems 4 Solutions to misuse (or no use) of locks Solution 1 - detection o use static or dynamic checking tools to help track down misuses of locking primitives (synchronization bugs) o How much can you detect? Solution 2 - prevention o have the compiler insert the synchronization primitives for you automatically o Which errors can be prevented this way, and which can’t?
CS533 - Concepts of Operating Systems 5 Solution 1: Checking tools (class 2 cont.) Eraser o A dynamic checker that uses binary re-writing techniques o Gathers an “execution history” of reads, writes and lock acquisitions o Evaluates consistency with rules Is it enough to simply check that some lock is held whenever a global variable is accessed?
CS533 - Concepts of Operating Systems 6 Automated checking of conventions Eraser doesn’t know ahead of time which locks protect which variables It infers which locks protect which variables using a lock-set algorithm o Assume all locks are candidates for a variable ( C(v) is full) o For each access take intersection of C(v) and locks held by thread and make these the candidate set C(v) o If C(v) becomes empty, issue warning
CS533 - Concepts of Operating Systems 7 Improving the locking discipline The standard approach produces many false positives that arise due to special cases: Initialization o No need to lock if no thread has a reference yet Read sharing o No need to lock if all threads are readers Reader/writer locking o Distinguish concurrent readers from concurrent readers and writers
CS533 - Concepts of Operating Systems 8 Improved algorithm virgin exclusive shared Modified (race?) rd, wr First thread wr rd, new thread wr, new thread wr rd
CS533 - Concepts of Operating Systems 9 What can’t it detect? Deadlocks? Races that do not manifest themselves in this particular execution run It can’t prove the absence of errors, it can only show the presence of errors
CS533 - Concepts of Operating Systems 10 Solution 2: Monitors Monitors employ two key concepts, both of which can be automated by a compiler: o Encapsulation: Local data variables are accessible only via the monitor’s entry procedures (like methods) o Mutual exclusion: The entry procedures are treated as critical sections
CS533 - Concepts of Operating Systems 11 Two kinds of synchronization Mutual exclusion o Only one at a time in the critical section Condition synchronization o Wait (block) until a certain condition holds o Signal (unblock) waiting threads when the condition holds
CS533 - Concepts of Operating Systems 12 Logical view of monitor structures initialization code “entry” methods y x shared data condition variables monitor entry queue List of threads waiting to enter the monitor Can be called from outside the monitor. Only one active at any moment. Local to monitor (Each has an associated list of waiting threads) local methods
CS533 - Concepts of Operating Systems 13 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures?
CS533 - Concepts of Operating Systems 14 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures? o Will spinning locks work?
CS533 - Concepts of Operating Systems 15 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures? o Will spinning locks work? o Will yielding locks work?
CS533 - Concepts of Operating Systems 16 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures? o Will spinning locks work? o Will yielding locks work? o What if we don’t have atomic instructions?
CS533 - Concepts of Operating Systems 17 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures? o Will spinning locks work? o Will yielding locks work? o What if we don’t have atomic instructions? Idea 1 (assuming uniprocessor): o Disable interrupts during monitor procedures
CS533 - Concepts of Operating Systems 18 A Simple Example Goal: to build a blocking mutex lock using monitors o Monitor procedures are “acquire” and “release” Demonstrate use of interrupt disabling on a uniprocessor to implement mutual exclusion within the monitor procedures
CS533 - Concepts of Operating Systems 19 Using monitors to build a blocking mutex Blocking_mutex:monitor Begin busy:boolean; nonbusy:condition; busy:=false; // initial value Procedure acquire() Begin if busy then nonbusy.wait; busy:=true; End Procedure release() Begin busy:=false; nonbusy.signal End; End Blocking_mutex;
CS533 - Concepts of Operating Systems 20 Using monitors to build a blocking mutex Blocking_mutex:monitor Begin busy:boolean; nonbusy:condition; Busy:=false; // initial value Procedure acquire() Begin<----- disable interrupts if busy then nonbusy.wait; busy:=true; End<----- enable interrupts Procedure release() Begin<----- disable interrupts busy:=false; nonbusy.signal End;<----- enable interrupts End Blocking_mutex;
CS533 - Concepts of Operating Systems 21 Using monitors to build a blocking mutex Blocking_mutex:monitor Begin busy:boolean; nonbusy:condition; Busy:=false; // initial value Procedure acquire() Begin----- disable interrupts if busy then nonbusy.wait; <----- ???? busy:=true; End----- enable interrupts Procedure release() Begin----- disable interrupts busy:=false; nonbusy.signal<----- ???? End;----- enable interrupts End Blocking_mutex;
CS533 - Concepts of Operating Systems 22 Implementing condition variables Wait o Add process to queue of processes waiting on this condition o Suspend process o Release monitor’s mutual exclusion Wake up / schedule next process trying to enter monitor Reenable interrupts? Signal o Wake up / schedule first process waiting on this condition o Release monitor’s mutual exclusion by enabling interrupts? o Suspend yourself On what? … and how do you ever wake up again?
CS533 - Concepts of Operating Systems 23 Implementing mutual exclusion for monitors How can we implement mutual exclusion for monitor procedures? o Will spinning locks work? o Will yielding locks work? o What if we don’t have atomic instructions? Idea 1: o Disable interrupts during monitor procedures Idea 2: o Use binary semaphores
CS533 - Concepts of Operating Systems 24 Building monitors from binary semaphores See example in paper
CS533 - Concepts of Operating Systems 25 Bounded buffer solution with monitors process Producer begin loop BoundedBuffer.append(c) end loop end Producer process Consumer begin loop BoundedBuffer.remove(c) end loop end Consumer BoundedBuffer: monitor var buffer :...; nextIn, nextOut :... ; procedure append (c: char) begin... end procedure remove (var c: char) begin... end end BoundedBuffer
CS533 - Concepts of Operating Systems 26 Bounded buffer solution with monitors BoundedBuffer: monitor var buffer : array[0..n-1] of char nextIn,nextOut : 0..n-1 := 0 Count : 0..n := 0 nonEmpty, nonFull : condition procedure append(c:char) procedure remove(var c: char) begin begin if (Count = n) then if (Count = n) then wait(nonFull) wait(nonEmpty) end if end if buffer[nextIn] := c c := buffer[nextOut] nextIn := nextIn+1 mod n nextOut := nextOut+1 mod n Count := Count+1 Count := Count-1 signal(nonEmpty) signal(nonFull) end append end remove end BoundedBuffer
CS533 - Concepts of Operating Systems 27 Alarm clock example AlarmClock: monitor Begin now: integer; wakeup: condition; now := 0; Procedure wakeme(n: integer); Begin alarmsetting: integer; alarmsetting := now + n; While now < alarmsetting do wakeup.wait (alarmsetting); wakeup.signal; End; Procedure tick; Begin now := now + 1; wakeup.signal; End; End AlarmClock;
CS533 - Concepts of Operating Systems 28 Semantics of condition variables How many blocked threads should be woken on a signal? Which blocked thread should be woken on a signal? In what order should newly awoken threads acquire the mutex? Should the signaler immediately free the mutex? o If so, what if it has more work to do? o If not, how can the signaled process continue? What if signal is called before the first wait?
CS533 - Concepts of Operating Systems 29 Subtle race conditions Why does wait on a condition variable need to “atomically” unlock the mutex and block the thread? Why does the thread need to re-lock the mutex when it wakes up from wait? o Can it assume that the condition it waited on now holds?
CS533 - Concepts of Operating Systems 30 Comparison with thread primitives How do Hoare’s monitors compare to the use of mutexes and condition variables described by Birrell?
CS533 - Concepts of Operating Systems 31 Deadlock (nested monitor problem) Procedure Get(); BEGIN LOCK a DO LOCK b DO WHILE NOT ready DO wait(b,c) END; END; END Get; Procedure Give(); BEGIN LOCK a DO LOCK b DO ready := TRUE; signal(c); END; END Give;
CS533 - Concepts of Operating Systems 32 Reader/writer locking Writers exclude readers and writers Readers exclude writers but not readers Example (page 15, Birrell) o Good use of broadcast in ReleaseExclusive() o Results in “spurious wake-ups” o … and “spurious lock conflicts” o How could you use signal instead? Move signal/broadcast call after release of mutex? o Advantages? Disadvantages? Can we avoid writer starvation?