So far... TDDD36 Secure Mobile Systems Systems Software Lecture 2: Semaphores & Monitors • Seen one method for dealing with mutual exclusion when sharing common resources: busy waiting Simin Nadjm-Tehrani Real-time Systems Laboratory Department of Computer and Information Science Linköping University Project course TDDD36 Systems software module 33 pages Autumn 2012 This lecture • How can the mutual exclusion and synchronisation problems be solved with other constructs? – Semaphore and monitor • What do we gain by using the support in OS or programming language? Project course TDDD36 Systems software module 3 of 33 Autumn 2012 Semaphores • A semaphore S is a non-negative integer variable on which only two operations wait and signal can be performed 2 of 33 Autumn 2012 Summary of early solutions • Busy waiting solutions to mutual exclusion problems are: – Difficult to implement consider n processes instead of 2 in solution from last lecture! – Wasteful for the CPU as a resource • But... – They do not require any support • Would be useful to have support from an operating system or a programming language Project course TDDD36 Systems software module 4 of 33 Autumn 2012 Recall: two general problems • Mutual exclusion Process Pi { entry-protocol critical-section exit-protocol non-critical-section } wait(S) if S > 0 then S = S-1 else suspend the process calling wait(S) signal(S) if some process P has been suspended by an earlier wait(S), then wake up P else S = S+1 Project course TDDD36 Systems software module Project course TDDD36 Systems software module 5 of 33 Autumn 2012 • Condition synchronisation • Ex: Compute the interest when all transactions have been processed Project course TDDD36 Systems software module 6 of 33 Autumn 2012 1 Using a semaphore ... • Let’s use a semaphore with the following implementation for solving mutual exclusion wait(S) if S > 0 then S = S-1 else suspend the process calling wait(S) signal(S) if some process P has been suspended by an earlier wait(S), then wake up P else S = S+1 Project course TDDD36 Systems software module 7 of 33 Autumn 2012 Mutual exclusion var mex: semaphore; (* initially 1 *) process Pi; loop wait(mex); critical_section; signal(mex); non_critical_section; end end Pi; Project course TDDD36 Systems software module Food for thought Questions: • How does the program behave with initial value 0 for the semaphore? • If there are two processes, what is the maximum value of mex? • If there are n processes? Project course TDDD36 Systems software module 9 of 33 Autumn 2012 Counting semaphores • When more than one instance of a resource is available, e.g. print servers • Processes can use up to max available but no more • The semaphore can be initialised to provide access for n processes Project course TDDD36 Systems software module Recall: two general problems 10 of 33 Autumn 2012 Condition synchronisation var condition:semaphore; (* initially 0*) • Mutual exclusion Process Pi { entry-protocol critical-section exit-protocol non-critical-section } process P1; (* waiting process *) ... wait(condition) ... end P1; process P2; (* signalling process *) ... signal(condition) ... end P2; • Condition synchronisation • Ex: Compute the interest when all transactions have been processed Project course TDDD36 Systems software module 8 of 33 Autumn 2012 11 of 33 Autumn 2012 Project course TDDD36 Systems software module 12 of 33 Autumn 2012 2 Semaphore implementations • Wait and Signal are implemented as atomic operations • Semaphore variable is always initialised as non-negative But • Which process to wake up among all suspended ones is not specified Project course TDDD36 Systems software module • For programmer wait and signal are atomic (indivisible) operations • In the supporting environment, atomicity has to be assured by: – allowing only one wait/signal to operate on a semaphore at any one time e.g. by • disabling interrupts during execution • busy waiting on entry to semaphore • hardware support (e.g. test-and-set operations) for locking before wait/signal 13 of 33 Autumn 2012 Spin locks Project course TDDD36 Systems software module 14 of 33 Autumn 2012 Semaphore implementations • Wait and Signal are implemented as atomic operations • Semaphore is always initialised as nonnegative • The original definitions of wait & signal just used a version of busy waiting to implement the semaphore: But • Which process to wake up among all suspended ones is not specified wait(s): while s ≤ 0 do nothing; s = s-1 signal(s): s = s+1 Project course TDDD36 Systems software module Atomicity: alternatives 15 of 33 Autumn 2012 Different implementations process P1; process P2; process P3; … … … wait(s) wait(s) wait(s) … … … signal(s) signal(s) signal(s) … … … end; end; end; Project course TDDD36 Systems software module 16 of 33 Autumn 2012 Semaphores vs. Busy waiting • For long critical sections, semaphores more efficient in using CPU • Better code organisation, less errors? • What about problems with deadlock and starvation? • We will come back to these ... One queue/semaphore at run-time: Project course TDDD36 Systems software module 17 of 33 Autumn 2012 Project course TDDD36 Systems software module 18 of 33 Autumn 2012 3 Example process A while (true){ print(A) print(K) } process B while (true) { print(T) print(C) } Insert semaphores so that a sequence of “TACK”s is printed out. Project course TDDD36 Systems software module 19 of 33 Autumn 2012 Student solution var S: semaphore (* initially 1 *) var Z: semaphore (* initially 1 *) process A process B while (true){ while (true) { wait(S); wait(S); print(A); print(T); signal(S); wait(Z); wait(Z); signal(S); print(K); print(C); signal(Z) signal(Z) } } Project course TDDD36 Systems software module 20 of 33 Autumn 2012 What is a monitor? Overview • A programming abstraction consisting of: – A data structure on which programmer can define operations – which can only be run one at a time – Condition variables for synchronisation Shared data Condition variables X, Y • Encapsulates shared data that several processes can operate upon • All access is with mutual exclusion • Pre object-orientation! Operations on Shared data Initialisation code [Hoare 74] Project course TDDD36 Systems software module 21 of 33 Autumn 2012 Project course TDDD36 Systems software module Condition variables 22 of 33 Autumn 2012 Example: Bounded buffer (* in some language that supports monitors *) • Declared as special synchronisation variables: Condition X; • With two designated operations: wait(X): suspend the calling process signal(X): if there are suspended processes on this variable, wake one up Project course TDDD36 Systems software module 23 of 33 Autumn 2012 monitor BoundedBuffer; Buf: array [0..SizeOfBuffer] of integer; Base, Top: integer; Count: integer; NotFull, NotEmpty: condition; operation ti A Append(E: d(E integer); i t ) ... end Append; operation Take(var E: integer); ... end Take; begin <initialize> (* set Base,Top,Count to 0 *) end BoundedBuffer; Project course TDDD36 Systems software module 24 of 33 Autumn 2012 4 Operation Append operation Append (E: integer); begin if Count == SizeOfBuffer + 1 then wait(NotFull); Buff[Top] = E; Top = (Top + 1) mod SizeOfBuffer; Count = Count + 1; signal(NotEmpty) end Append; Project course TDDD36 Systems software module Operation Take operation Take (var E: integer); begin if Count == 0 then wait(NotEmpty); E = Buff[Base]; Base = (Base + 1) mod SizeOfBuffer; Count = Count - 1; signal(NotFull) end Take; 25 of 33 Autumn 2012 Project course TDDD36 Systems software module 26 of 33 Autumn 2012 Producer-Consumer problem process Producer; var Element: integer; begin loop Produce(Element); Append(Element) end end Producer; process Consumer; var Element: integer; begin loop Take(Element); Consume(Element) end end Consumer; Project course TDDD36 Systems software module 27 of 33 Autumn 2012 Observations • Programmer uses wait and signal inside the code that defines the operations on the shared data structure Note: • The condition variable has no values assigned to it • The queue associated with each variable is the main synchronisation mechanism • Different semantics from semaphore operations for wait and signal Project course TDDD36 Systems software module 28 of 33 Autumn 2012 Process queues Process P1 Queue of processes wanting to execute some monitor operation How does it work? Shared data Condition variables X, Y queue of processes waiting for X … wait(X) X: Y: Process P4 queue off processes waiting for Y … signal(X) Operations on These operations may use wait/signal … t Shared data Initialisation code Which process to run at time t? on X, Y Project course TDDD36 Systems software module P Process P2 time 29 of 33 Autumn 2012 Project course TDDD36 Systems software module 30 of 33 Autumn 2012 5 Options • Monitors have the same power as semaphores but are at a higher level of abstraction • Original Hoare monitor: let the woken up process (P1) continue – Exercise: Try implementing producerconsumer solution with semaphores! What if there are several processes waiting on X? • Monitor has two different mechanisms for handling synchronisation and for data communication • Pragmatic solution (Java): let the signalling process continue, and wake up P1 once P4 is suspended/exits • Mutually exclusive access to data automatic, but matching waits and signals still a problem! P1 has to check for condition X when woken up! Project course TDDD36 Systems software module Summary 31 of 33 Autumn 2012 Project course TDDD36 Systems software module 32 of 33 Autumn 2012 Questions? Project course TDDD36 Systems software module 33 of 33 Autumn 2012 6