CPS110: Reader-writer locks

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

1 Interprocess Communication 1. Ways of passing information 2. Guarded critical activities (e.g. updating shared data) 3. Proper sequencing in case of.
Ch 7 B.
Chapter 6: Process Synchronization
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Concurrent Programming James Adkison 02/28/2008. What is concurrency? “happens-before relation – A happens before B if A and B belong to the same process.
EEE 435 Principles of Operating Systems Interprocess Communication Pt II (Modern Operating Systems 2.3)
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 13: October 12, 2010 Instructor: Bhuvan Urgaonkar.
6.5 Semaphore Can only be accessed via two indivisible (atomic) operations wait (S) { while S
1 Semaphores and Monitors: High-level Synchronization Constructs.
COSC 3407: Operating Systems Lecture 8: Semaphores, Monitors and Condition Variables.
CS 162 Discussion Section Week 3. Who am I? Mosharaf Chowdhury Office 651 Soda 4-5PM.
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
Monitors CSCI 444/544 Operating Systems Fall 2008.
Semaphores CSCI 444/544 Operating Systems Fall 2008.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
Semaphores Questions answered in this lecture: Why are semaphores necessary? How are semaphores used for mutual exclusion? How are semaphores used for.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
Semaphores and Bounded Buffer Andy Wang Operating Systems COP 4610 / CGS 5765.
6.3 Peterson’s Solution The two processes share two variables: Int turn; Boolean flag[2] The variable turn indicates whose turn it is to enter the critical.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 14: October 14, 2010 Instructor: Bhuvan Urgaonkar.
4061 Session 21 (4/3). Today Thread Synchronization –Condition Variables –Monitors –Read-Write Locks.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Lecture 11: Synchronization (Chapter 6, cont)
Operating Systems CSE 411 CPU Management Dec Lecture Instructor: Bhuvan Urgaonkar.
13/03/07Week 21 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Operating Systems COMP 4850/CISG 5550 Interprocess Communication, Part II Dr. James Money.
6.1 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts with Java – 8 th Edition Module 6: Process Synchronization.
1 Processes and Threads Part II Chapter Processes 2.2 Threads 2.3 Interprocess communication 2.4 Classical IPC problems 2.5 Scheduling.
Multi-programming in THE Landon Cox February 3, 2016.
CS 311/350/550 Semaphores. Semaphores – General Idea Allows two or more concurrent threads to coordinate through signaling/waiting Has four main operations.
6.1 Silberschatz, Galvin and Gagne ©2005 Operating System Principles 6.5 Semaphore Less complicated than the hardware-based solutions Semaphore S – integer.
Interprocess Communication Race Conditions
CS703 - Advanced Operating Systems
Multi-programming in THE
EMERALDS Landon Cox March 22, 2017.
CS703 – Advanced Operating Systems
Process Synchronization: Semaphores
Background on the need for Synchronization
Process Synchronization
CS533 Concepts of Operating Systems Class 3
Operating Systems CMPSC 473
CSE451 Basic Synchronization Spring 2001
Multi-programming in THE
Lecture 13: Producer-Consumer and Semaphores
Semaphores and Bounded Buffer
Anthony D. Joseph and Ion Stoica
Threading And Parallel Programming Constructs
Semaphore Originally called P() and V() wait (S) { while S <= 0
Process Synchronization
Synchronization Hank Levy 1.
Lecture 2 Part 2 Process Synchronization
CS533 Concepts of Operating Systems Class 3
CSE 451: Operating Systems Autumn Lecture 8 Semaphores and Monitors
Slides by Prof. Landon Cox and Vamsi Thummala
CSE 451: Operating Systems Autumn Lecture 7 Semaphores and Monitors
Kernel Synchronization II
September 12, 2012 Ion Stoica CS162 Operating Systems and Systems Programming Lecture 5 Semaphores, Conditional Variables.
Lecture 13: Producer-Consumer and Semaphores
CSE 451: Operating Systems Winter Module 7 Semaphores and Monitors
Synchronization Hank Levy 1.
CSE 153 Design of Operating Systems Winter 19
Chapter 7: Synchronization Examples
CSE 153 Design of Operating Systems Winter 2019
EECE.4810/EECE.5730 Operating Systems
EECE.4810/EECE.5730 Operating Systems
Don Porter Portions courtesy Emmett Witchel
CSE 542: Operating Systems
Review The Critical Section problem Peterson’s Algorithm
Presentation transcript:

CPS110: Reader-writer locks Landon Cox January 26, 2009

Locks thus far Lock anytime shared data is read/written Ensures correctness Only one thread can read/write at a time Would like more concurrency How, without exposing violated invariants? Allow multiple threads to read (as long as none are writing)

Problem definition Shared state that many threads want to access Many more reads than writes ACES, Ebay, any large database When no writers, allow multiple readers One writer at a time, when no readers Goal: build reader-writer locks using monitors

Layers of synchronization Queue, TMM, Soda machine, Disk scheduler Concurrent program Higher-level synchronization (reader-writer functions) High-level synchronization (locks, monitors, semaphores) Today Coming lectures Project 1 lib Hardware (load/store, interrupt enable/disable, test&set) Advanced HW course

Reader-writer interface readerStart (called when thread begins reading) readerFinish (called when thread is finished reading) writerStart (called when thread begins writing) writerFinish (called when thread is finished writing) If no threads between writerStart/writerFinish Many threads between readerStart/readerFinish Only 1 thread between writerStart/writerFinish

Solving reader-writer locks What are the variables/shared state? Number of readers (numReaders) Number of writers (numWriters) Locks? 1 to protect all shared state (rwLock) Mutual exclusion? Only one thread in functions at a time Ordering constraints? readerStart must wait if there are writers writerStart must wait if there are readers or writers Due to overlap, use one CV (readerOrWriterFinishCV)

Reader-writer code writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) numReaders-- broadcast (rowfCV) unlock (RWLock) }

Reader-writer code Sure, both are protected by RWLock. writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) broadcast (rowfCV) numReaders-- unlock (RWLock) } Sure, both are protected by RWLock.

Reader-writer code writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) numReaders-- broadcast (rowfCV) unlock (RWLock) } If writer leaves with waiting readers and writers, who wins?

Reader-writer code How long might a writer have to wait? writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) numReaders-- broadcast (rowfCV) unlock (RWLock) } How long might a writer have to wait?

Prioritizing waiting writers writerStart () { lock (RWLock) while (actWriters > 0 || numReaders > 0) { waitWriters++ wait (RWlock, rowfCV) waitWriters-- } actWriters++; unlock (RWLock) readerStart () { lock (RWLock) while ((actWriters + waitWriters) > 0){ wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) readerFinish () { lock (RWLock) numReaders-- broadcast (rowfCV) unlock (RWLock) } writerFinish () { lock (RWLock) actWriters-- broadcast (rowfCV) unlock (RWLock) }

When to use broadcast Still have the spurious wakeup problem More than one thread might need to run If writer leaves, waiting readers should be woken Signal could wakeup “wrong” thread “Wrong” thread checks condition, re-sleeps (producer-consumer problem) Still have the spurious wakeup problem (let’s try to fix that in our no-prior. sol.)

Removing spurious wakeups writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) numReaders— if (numReaders == 0) broadcast (rowfCV) unlock (RWLock) }

Is it ok to use signal? writerStart () { lock (RWLock) while (numWriters > 0 || numReaders > 0) { wait (RWlock, rowfCV) } numWriters++; unlock (RWLock) readerStart () { lock (RWLock) while (numWriters > 0) { wait (RWlock, rowfCV) } numReaders++ unlock (RWLock) writerFinish () { lock (RWLock) numWriters-- broadcast (rowfCV) unlock (RWLock) } readerFinish () { lock (RWLock) numReaders— if (numReaders == 0) signal (rowfCV) unlock (RWLock) } Sure: won’t wake up any readers, only one writer can run anyway

Reader-writer interface vs locks R-W interface looks a lot like locking *Start ~ lock *Finish ~ unlock Standard terminology Four functions called “reader-writer locks” Between readStart/readFinish has “read lock” Between writeStart/writeFinish has “write lock” Pros/cons of R-W vs standard locks? Trade-off concurrency for complexity Must know how data is being accessed in critical section

Course administration Project 1 Due February 18 Should be able to do disk scheduler Can start thread library next week Start early (i.e., this week)! Other questions/concerns?

Semaphores First defined by Dijkstra in late 60s Two operations: up and down // aka “V” (“verhogen”) up () { // begin atomic value++ // end atomic } // aka “P” (“proberen”) down () { do { // begin atomic if (value > 0) { value-- break } // end atomic } while (1) What is going on here? Can value ever be < 0?

More semaphores Key state of a semaphore is its value Initial value determines semaphore’s behavior Value cannot be accessed outside semaphor (i.e. there is no semaphore.getValue() call) Semaphores can be both synchronization types Mutual exclusion (like locks) Ordering constraints (like monitors)

Semaphore mutual exclusion Ensure that 1 (or < N) thread is in critical section How do we make a semaphore act like a lock? Set initial value to 1 (or N) Like lock/unlock, but more general (could allow 2 threads in critical section if initial value = 2) Lock is equivalent to a binary semaphore s.down (); // critical section s.up ();

Semaphore ordering constraints Thread A waits for B before proceeding How to make a semaphore behave like a monitor? Set initial value of semaphore to 0 A is guaranteed to wait for B to finish Doesn’t matter if A or B run first Like a CV in which condition is “sem.value==0” Can think of as a “prefab” condition variable // Thread A s.down (); // continue // Thread B // do task s.up ();

Prod.-cons. with semaphores Same before-after constraints If buffer empty, consumer waits for producer If buffer full, producer waits for consumer Semaphore assignments mutex (binary semaphore) fullBuffers (counts number of full slots) emptyBuffers (counts number of empty slots)

Prod.-cons. with semaphores Initial semaphore values? Mutual exclusion sem mutex (?) Machine is initially empty sem fullBuffers (?) sem emptyBuffers (?)

Prod.-cons. with semaphores Initial semaphore values Mutual exclusion sem mutex (1) Machine is initially empty sem fullBuffers (0) sem emptyBuffers (MaxSodas)

Prod.-cons. with semaphores Semaphore mutex(1),fullBuffers(0),emptyBuffers(MaxSodas) consumer () { down (fullBuffers) down (mutex) take soda out up (mutex) up (emptyBuffers) } producer () { down (emptyBuffers) down (mutex) put soda in up (mutex) up (fullBuffers) } Use one semaphore for fullBuffers and emptyBuffers? Remember semaphores are like prefab CVs.

Prod.-cons. with semaphores Semaphore mutex(1),fullBuffers(0),emptyBuffers(MaxSodas) consumer () { down (mutex) down (fullBuffers) take soda out up (emptyBuffers) up (mutex) } producer () { down (mutex) down (emptyBuffers) put soda in up (fullBuffers) up (mutex) } 2 1 Does the order of the down calls matter? Yes. Can cause “deadlock.”

Prod.-cons. with semaphores Semaphore mutex(1),fullBuffers(0),emptyBuffers(MaxSodas) consumer () { down (fullBuffers) down (mutex) take soda out up (emptyBuffers) up (mutex) } producer () { down (emptyBuffers) down (mutex) put soda in up (fullBuffers) up (mutex) } Does the order of the up calls matter? Not for correctness (possible efficiency issues).

Prod.-cons. with semaphores Semaphore mutex(1),fullBuffers(0),emptyBuffers(MaxSodas) consumer () { down (fullBuffers) down (mutex) take soda out up (mutex) up (emptyBuffers) } producer () { down (emptyBuffers) down (mutex) put soda in up (mutex) up (fullBuffers) } What about multiple consumers and/or producers? Doesn’t matter; solution stands.

Prod.-cons. with semaphores Semaphore mtx(1),fullBuffers(1),emptyBuffers(MaxSodas-1) consumer () { down (fullBuffers) down (mutex) take soda out up (mutex) up (emptyBuffers) } producer () { down (emptyBuffers) down (mutex) put soda in up (mutex) up (fullBuffers) } What if 1 full buffer and multiple consumers call down? Only one will see semaphore at 1, rest see at 0.

Monitors vs. semaphores Separate mutual exclusion and ordering Semaphores Provide both with same mechanism Semaphores are more “elegant” Single mechanism Can be harder to program

Monitors vs. semaphores Where are the conditions in both? Which is more flexible? Why do monitors need a lock, but not semaphores? // Monitors lock (mutex) while (condition) { wait (CV, mutex) } unlock (mutex) // Semaphores down (semaphore)

Monitors vs. semaphores When are semaphores appropriate? When shared integer maps naturally to problem at hand (i.e. when the condition involves a count of one thing) // Monitors lock (mutex) while (condition) { wait (CV, mutex) } unlock (mutex) // Semaphores down (semaphore)