Operating Systems CMPSC 473 Mutual Exclusion Lecture 14

  • Slides: 17
Download presentation
Operating Systems CMPSC 473 Mutual Exclusion Lecture 14: October 14, 2010 Instructor: Bhuvan Urgaonkar

Operating Systems CMPSC 473 Mutual Exclusion Lecture 14: October 14, 2010 Instructor: Bhuvan Urgaonkar

Mid-semester feedback • On Angel, format similar to SRTEs • Please submit by end

Mid-semester feedback • On Angel, format similar to SRTEs • Please submit by end of the week • Based on feedback so far: will do a revision of mutual exclusion related topics

Agenda • Some classic synchronization problems using semaphores • Last class – Producer/Consumer problem

Agenda • Some classic synchronization problems using semaphores • Last class – Producer/Consumer problem – Readers/Writers problem • Solution was free of deadlocks • Starvation problem • Today – Readers/Writers problem • Consider more carefully the definition of starvation – Dining Philosophers problem

Readers-Writers Problem • A data set shared among a number of concurrent processes –

Readers-Writers Problem • A data set shared among a number of concurrent processes – Readers – only read the data set; they do not perform any updates – Writers – can both read and write • Problem – allow multiple readers to read at the same time. Only one writer may access the shared data at a given time • Shared Data – – Data set Semaphore mutex initialized to 1 Semaphore wrt initialized to 1 Integer readcount initialized to 0

Readers-Writers Problem (Cont. ) mutex = 1 wrt = 1 readcount = 0 •

Readers-Writers Problem (Cont. ) mutex = 1 wrt = 1 readcount = 0 • The structure of a writer process do { wait (wrt) ; Allow only one // writing is performed writer at a time to write signal (wrt) ; } while (TRUE);

Readers-Writers Problem (Cont. ) • The structure of a reader process do { Proceed

Readers-Writers Problem (Cont. ) • The structure of a reader process do { Proceed only if wait (mutex) ; no writer is readcount ++ ; writing; disallowif (readcount == 1) wait (wrt) ; writers once wesignal (mutex) ; proceed // reading Signal a writer wait (mutex) ; only when there readcount - - ; if (readcount == 0) are no more signal (wrt) ; active readers signal (mutex) ; } while (TRUE); mutex = 1 wrt = 1 readcount = 0

Readers/Writers • Note that starvation is said to occur only when a process, despite

Readers/Writers • Note that starvation is said to occur only when a process, despite getting CPU, does not get to make use of it – Only writers are starved, not readers • Can we eliminate starvation for writers?

Dining-Philosophers Problem • Shared data – Bowl of rice (data set) – Semaphore chopstick

Dining-Philosophers Problem • Shared data – Bowl of rice (data set) – Semaphore chopstick [5] initialized to 1

Dining-Philosophers Problem (Cont. ) • The structure of Philosopher i: do { ); wait

Dining-Philosophers Problem (Cont. ) • The structure of Philosopher i: do { ); wait ( chopstick[i] ); wait ( chop. Stick[ (i + 1) % 5] // eat ); signal ( chopstick[i] ); signal (chopstick[ (i + 1) % 5] // think Deadlock? Starvation? What happens if all pick their left

Dining-Philosophers Problem (Cont. ) • Idea #1: Make the two wait operations occur together

Dining-Philosophers Problem (Cont. ) • Idea #1: Make the two wait operations occur together as an atomic unit (and the two signal operations) – Use another binary semaphore for this – Any problems with this?

Dining-Philosophers Problem (Cont. ) • Idea #2: Does it help if one of the

Dining-Philosophers Problem (Cont. ) • Idea #2: Does it help if one of the neighbors picks their left chopstick first and the other picks their right chopstick first? • What is the most # phils. that can eat simultaneously?

Bounded Buffer/ Producer Consumer Producer N=4 2 empty slots Consume 2 occupied slots •

Bounded Buffer/ Producer Consumer Producer N=4 2 empty slots Consume 2 occupied slots • Buffer has max capacity N • Producer can only add if buffer has room (i. e. , count < N) • Consumer can only remove if buffer has item (i. e. , count > 0)

Producer Consumer: Mutex mutex_lock m; Locks • Downside: Busy waiting int count = 0;

Producer Consumer: Mutex mutex_lock m; Locks • Downside: Busy waiting int count = 0; Produce() { while (count == N); mutex_lock (m); … ADD TO BUFFER, count++ … } mutex_unlock (m); Consume() { while (count ==0); mutex_lock (m); • Liveness guarantee depends on how lock is implemented – E. g. , – Peterson’s => Mutex and bounded wait – Test&set => Only mutex … REMOVE FROM BUFFER, count-- … } mutex_unlock (m);

Binary Semaphores == Mutex semaphore m = 1; Locks int count = 0; Produce()

Binary Semaphores == Mutex semaphore m = 1; Locks int count = 0; Produce() { while (count == N); wait (m); … ADD TO BUFFER, count++ … } signal (m); Consume() { while (count ==0); wait (m); … REMOVE FROM BUFFER, count-- … } signal (m);

semaphore sem = 1; semaphore full = 0; semaphore empty = N; Producer Consumer:

semaphore sem = 1; semaphore full = 0; semaphore empty = N; Producer Consumer: Semaphores Produce() { wait (empty); wait (sem); … ADD TO BUFFER, count++ … signal (sem); signal (full); } Consume() { wait (full); wait (sem); … REMOVE FROM BUFFER, signal (sem); signal (empty); } • Use three semaphores • Note important difference from condition variables – Signals are not lost • sem protects critical sections • full forces a consumer to wait till there is at least one item in buffer • empty ensures at most N items are produced count-- … between empty buffer and execution of a consumer

Producer Consumer: Semaphores semaphore sem = 1; int count = 0; Produce() { if

Producer Consumer: Semaphores semaphore sem = 1; int count = 0; Produce() { if (count == N) wait (sem); … ADD TO BUFFER, count++ … } signal (sem); • A non-working example – Identify the race condition here – That is, can a producer and consumer be in their critical sections simultaneously? Consume() { if (count == 0) wait (sem); … REMOVE FROM BUFFER, count-- … } signal (sem);

Producer Consumer: Semaphores semaphore sem = 1; int count = 0; mutex_lock m; Produce()

Producer Consumer: Semaphores semaphore sem = 1; int count = 0; mutex_lock m; Produce() { mutex_lock (m); if (count == N) wait (sem); … ADD TO BUFFER, count++ … signal (sem); mutex_unlock (m); } • A non-working example • What happens if a consumer acquires the lock before an item is added to the buffer? – Deadlock! Consume() { mutex_lock (m); if (count == 0) wait (sem); … REMOVE FROM BUFFER, count-- … signal (sem); mutex_unlock (m); }