CS162Operating Systems andSystems ProgrammingLecture 8Readers-WritersLanguage Support for SynchronizationSeptember 23, 2009Prof. John Kubiatowiczhttp://inst.eecs.berkeley.edu/~cs162Lec 8.29/23/09 Kubiatowicz CS162 ©UCB Fall 2009Review: Implementation of Locks by Disabling Interrupts• Key idea: maintain a lock variable and impose mutual exclusion only during operations on that variableint value = FREE;Acquire() {disable interrupts;if (value == BUSY) {put thread on wait queue;Go to sleep();// Enable interrupts?} else {value = BUSY;}enable interrupts;}Release() {disable interrupts;if (anyone on wait queue) {take thread off wait queuePlace on ready queue;} else {value = FREE;}enable interrupts;}Lec 8.39/23/09 Kubiatowicz CS162 ©UCB Fall 2009Review: How to Re-enable After Sleep()?• In Nachos, since ints are disabled when you call sleep:– Responsibility of the next thread to re-enable ints– When the sleeping thread wakes up, returns to acquire and re-enables interruptsThread AThread B..disable intssleepsleep returnenable ints...disable intsleepsleep returnenable ints..contextswitchcontextswitchLec 8.49/23/09 Kubiatowicz CS162 ©UCB Fall 2009Review: Locks using test&set• Can we build test&set locks without busy-waiting?– Can’t entirely, but can minimize!– Idea: only busy-wait to atomically check lock value• Note: sleep has to be sure to reset the guard variable– Why can’t we do it just before or just after the sleep?Release() {// Short busy-wait timewhile (test&set(guard));if anyone on wait queue {take thread off wait queuePlace on ready queue;} else {value = FREE;}guard = 0;int guard = 0;int value = FREE;Acquire() {// Short busy-wait timewhile (test&set(guard));if (value == BUSY) {put thread on wait queue;go to sleep() & guard = 0;} else {value = BUSY;guard = 0;}}Lec 8.59/23/09 Kubiatowicz CS162 ©UCB Fall 2009Review: Semaphores• Definition: a Semaphore has a non-negative integer value and supports the following two operations:– P(): an atomic operation that waits for semaphore to become positive, then decrements it by 1 » Think of this as the wait() operation– V(): an atomic operation that increments the semaphore by 1, waking up a waiting P, if any» This of this as the signal() operation– Only time can set integer directly is at initialization time• Semaphore from railway analogy– Here is a semaphore initialized to 2 for resource control:Value=2Value=1Value=0Value=1Value=0Value=2Lec 8.69/23/09 Kubiatowicz CS162 ©UCB Fall 2009Goals for Today• Continue with Synchronization Abstractions– Monitors and condition variables• Readers-Writers problem and solutoin• Language Support for SynchronizationNote: Some slides and/or pictures in the following areadapted from slides ©2005 Silberschatz, Galvin, and Gagne Note: Some slides and/or pictures in the following areadapted from slides ©2005 Silberschatz, Galvin, and Gagne. Many slides generated from my lecture notes by Kubiatowicz.Lec 8.79/23/09 Kubiatowicz CS162 ©UCB Fall 2009Review: Full Solution to Bounded BufferSemaphore fullBuffer = 0; // Initially, no cokeSemaphore emptyBuffers = numBuffers;// Initially, num empty slotsSemaphore mutex = 1; // No one using machineProducer(item) {emptyBuffers.P(); // Wait until spacemutex.P(); // Wait until buffer freeEnqueue(item);mutex.V();fullBuffers.V(); // Tell consumers there is// more coke}Consumer() {fullBuffers.P(); // Check if there’s a cokemutex.P(); // Wait until machine freeitem = Dequeue();mutex.V();emptyBuffers.V(); // tell producer need morereturn item;}Lec 8.89/23/09 Kubiatowicz CS162 ©UCB Fall 2009Discussion about Solution• Why asymmetry?– Producer does: emptyBuffer.P(), fullBuffer.V()– Consumer does: fullBuffer.P(), emptyBuffer.V()• Is order of P’s important?– Yes! Can cause deadlock:Producer(item) {mutex.P(); // Wait until buffer freeemptyBuffers.P();// Could wait forever!Enqueue(item);mutex.V();fullBuffers.V(); // Tell consumers more coke}• Is order of V’s important?– No, except that it might affect scheduling efficiency• What if we have 2 producers or 2 consumers?– Do we need to change anything?Lec 8.99/23/09 Kubiatowicz CS162 ©UCB Fall 2009Motivation for Monitors and Condition Variables• Semaphores are a huge step up, but:– They are confusing because they are dual purpose:» Both mutual exclusion and scheduling constraints» Example: the fact that flipping of P’s in bounded buffer gives deadlock is not immediately obvious– Cleaner idea: Use locksfor mutual exclusion and condition variablesfor scheduling constraints• Definition: Monitor: a lock and zero or more condition variables for managing concurrent access to shared data– Use of Monitors is a programming paradigm– Some languages like Java provide monitors in the language• The lock provides mutual exclusion to shared data:– Always acquire before accessing shared data structure– Always release after finishing with shared data– Lock initially freeLec 8.109/23/09 Kubiatowicz CS162 ©UCB Fall 2009Simple Monitor Example (version 1)• Here is an (infinite) synchronized queueLock lock;Queue queue;AddToQueue(item) {lock.Acquire(); // Lock shared dataqueue.enqueue(item); // Add itemlock.Release(); // Release Lock}RemoveFromQueue() {lock.Acquire(); // Lock shared dataitem = queue.dequeue();// Get next item or nulllock.Release(); // Release Lockreturn(item); // Might return null}• Not very interesting use of “Monitor”– It only uses a lock with no condition variables– Cannot put consumer to sleep if no work!Lec 8.119/23/09 Kubiatowicz CS162 ©UCB Fall 2009Condition Variables• How do we change the RemoveFromQueue() routine to wait until something is on the queue?– Could do this by keeping a count of the number of things on the queue (with semaphores), but error prone• Condition Variable: a queue of threads waiting for something insidea critical section– Key idea: allow sleeping inside critical section by atomically releasing lock at time we go to sleep– Contrast to semaphores: Can’t wait inside critical section• Operations:– Wait(&lock): Atomically release lock and go to sleep. Re-acquire lock later, before returning. – Signal(): Wake up one waiter, if any– Broadcast(): Wake up all waiters• Rule: Must hold lock when doing condition variable ops!– In Birrell paper, he says can perform signal() outside of lock – IGNORE HIM (this is only an optimization)Lec 8.129/23/09 Kubiatowicz CS162 ©UCB Fall 2009Complete
View Full Document