Synchronization Principles. Race Conditions Race Conditions: An Example...... spooler directory 4 5 6 7 8 out in 4 7 somefile.txt list.c scores.txt Process.

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.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
1 Chapter 5 Concurrency: Mutual Exclusion and Synchronization Principals of Concurrency Mutual Exclusion: Hardware Support Semaphores Readers/Writers Problem.
Global Environment Model. MUTUAL EXCLUSION PROBLEM The operations used by processes to access to common resources (critical sections) must be mutually.
1 Implementations: User-level Kernel-level User-level threads package each u.process defines its own thread policies! flexible mgt, scheduling etc…kernel.
Operating Systems: Sync
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
G53OPS Operating Systems
Chapter 2 Processes and Threads
Chapter 6: Process Synchronization
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
5.1 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts with Java – 8 th Edition Chapter 5: CPU Scheduling.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
EEE 435 Principles of Operating Systems Interprocess Communication Pt II (Modern Operating Systems 2.3)
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
Mutual Exclusion.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
Interprocess Communication
CY2003 Computer Systems Lecture 05 Semaphores - Theory.
EEE 435 Principles of Operating Systems Interprocess Communication Pt I (Modern Operating Systems 2.3)
1 Threads CSCE 351: Operating System Kernels Witawas Srisa-an Chapter 4-5.
Interprocess Communication
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Concurrency: Mutual Exclusion, Synchronization, Deadlock, and Starvation in Representative Operating Systems.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
A. Frank - P. Weisberg Operating Systems Introduction to Cooperating Processes.
1 Outline Processes Threads Inter-process communication (IPC) Classical IPC problems Scheduling.
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
Concurrency 1 CS502 Spring 2006 Thought experiment static int y = 0; int main(int argc, char **argv) { extern int y; y = y + 1; return 0; }
Adopted from and based on Textbook: Operating System Concepts – 8th Edition, by Silberschatz, Galvin and Gagne Updated and Modified by Dr. Abdullah Basuhail,
Process Synchronization Ch. 4.4 – Cooperating Processes Ch. 7 – Concurrency.
1 Race Conditions/Mutual Exclusion Segment of code of a process where a shared resource is accessed (changing global variables, writing files etc) is called.
OPERATING SYSTEM LESSON 6 INTERPROCESS COMMUNICATION.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
MODERN OPERATING SYSTEMS Third Edition ANDREW S. TANENBAUM Chapter 2 Processes and Threads Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall,
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Mutual Exclusion.
Mutual Exclusion. Readings r Silbershatz: Chapter 6.
Midterm 1 – Wednesday, June 4  Chapters 1-3: understand material as it relates to concepts covered  Chapter 4 - Processes: 4.1 Process Concept 4.2 Process.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts Essentials – 9 th Edition Chapter 5: Process Synchronization.
Background Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms to ensure the orderly execution.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
1 Processes and Threads Part II Chapter Processes 2.2 Threads 2.3 Interprocess communication 2.4 Classical IPC problems 2.5 Scheduling.
Operating System Concepts and Techniques Lecture 13 Interprocess communication-2 M. Naghibzadeh Reference M. Naghibzadeh, Operating System Concepts and.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Synchronization.
Process Synchronization. Objectives To introduce the critical-section problem, whose solutions can be used to ensure the consistency of shared data To.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
Semaphores Reference –text: Tanenbaum ch
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
Transmitter Interrupts Review of Receiver Interrupts How to Handle Transmitter Interrupts? Critical Regions Text: Tanenbaum
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Interprocess Communication Race Conditions
Semaphores Reference text: Tanenbaum ch
Process Synchronization
Process Synchronization: Semaphores
Background on the need for Synchronization
Chapter 5: Process Synchronization
Lecture 13: Producer-Consumer and Semaphores
MODERN OPERATING SYSTEMS Third Edition ANDREW S
Transmitter Interrupts
Lecture 13: Producer-Consumer and Semaphores
CSE 153 Design of Operating Systems Winter 19
CSE 153 Design of Operating Systems Winter 2019
CS333 Intro to Operating Systems
Chapter 6: Synchronization Tools
Semaphores Reference text: Tanenbaum ch
Presentation transcript:

Synchronization Principles

Race Conditions

Race Conditions: An Example spooler directory out in 4 7 somefile.txt list.c scores.txt Process A Process B (next job to print) (next available slot in queue) Global Variables

spooler directory out in 4 7 somefile.txt list.c scores.txt Process A Process B (next to print) (next available slot) Process A gets a time slice. It does some work. Then it wants to print. It gets the next available slot in the spooler directory. Then it gets swapped out. Global Variables 77

spooler directory out in 4 7 somefile.txt list.c scores.txt Process A Process B (next to print) (next available slot) Process B now gets a time slice. It also wants to print. It gets the next available slot in the spooler directory and stores the path to the file there. Then it gets swapped out. Global Variables 7 7 b_file.txt

spooler directory out in 4 7 somefile.txt list.c scores.txt Process A Process B (next to print) (next available slot) Process A now gets a time slice. It has what it believes is the next available slot in the spooler directory. It stores the path to it’s file there... Global Variables 7 7 a_file.txt b_file.txt

spooler directory out in 7 12 a_file.txt Process A Process B (next to print) (next available slot) Eventually, the spooler prints the file pointed to by entry 7 in the spooler directory. User A gets their printout. User B has no clue what happened.

Critical Regions One way to address the problem of race conditions is to make sure that while one program is using a shared variable or a shared file, other programs are excluded from doing so. This is called mutual exclusion. The part of a program where a shared resource is accessed is called a critical region. If we could guarantee that two programs were not both executing their critical regions at the same time, we could avoid race conditions.

The following four conditions must hold to avoid a race condition: * No two processes may be simultaneously inside their critical regions * No assumptions may be made about speeds, scheduling, or the number of CPUs * No process running outside of its critical region may block another process * No process should have to wait forever to enter its critical region.

Solving the Spooler Problem Using Critical Regions

Process A Process B Process A enters its critical region Process A leaves its critical region Process A is swapped out. Process B attempts to enter its critical region Blocked Process B enters its critical region

High Level Language Statements are not atomic! Process A Process B shared variable “balance” balance = balance + amount; balance = balance - amount; loadr1, balance loadr2, amount addr1, r2 storer1, balance loadr1, balance loadr2, amount subr1, r2 storer1, balance r1 balance a balance new balance a restore the registers

Achieving Mutual Exclusion Disabling Interrupts Lock Variables Strict Alternation Petersen’s Solution The TSL Instruction with busy waiting

Disabling Interrupts Let process A disable interrupts just as it enters its critical section. Now it can examine and update shared resources without concern. The timer interrupt won’t be caught until interrupts are enabled again. Process A then enables interrupts as it leaves its critical section. Problem: What if a user program disables interrupts, but for some reason never enables them again? It is okay for the kernel to disable interrupts, but not for a user program to do so.

Lock Variables Consider having a single shared variable that all processes use to test whether or not they can enter their critical section. If the value of the lock is 0, a process sets it to 1 and enters its critical region. If it is 1, it waits until the lock becomes 0.

Lock Variables Consider having a single shared variable that all processes use to test whether or not they can enter their critical section. If the value of the lock is 0, a process sets it to 1 and enters its critical region. If it is 1, it waits until the lock becomes 0. while (lock == 1); lock = 1; // critical region... what happens if a context switch occurs here?

Strict Alternation Again, use a single shared variable as a lock variable. However, this time we allow process A to enter only when the value of the lock is 0 and process B can enter only when the lock is 1.

Process A Process B Process A checks the lock variable. It is 0, so it enters its critical region lock variable 0

Process A Process B Process A checks the lock variable. It is 0, so it enters its critical region lock variable 0 Process B checks the lock variable. It is 0, so it cannot enter its critical region. It loops, waiting for the lock to change to 1. busy wait

Process A Process B Process A exits its critical region and changes the lock to 1. lock variable 1 busy wait Process B notices that the lock is now set to 1 and enters its critical region.

Process A Process B lock variable 0 busy wait When it leaves its critical region, process B changes to lock to 0. What are the problems here? Busy waiting (a spin lock) wastes CPU time Processes must alternate. Recall that process A can enter only when the value of the lock is 0. If A leaves it’s critical section and B never executes it’s critical section, the lock never gets set back to 0!

Petersen’s Solution Consider the following code: #define N 2 int lock; int interested[N]; void enter_region(int process) { int other; other = 1 – process; // flips it interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } void leave_region(int process) { interested[process] = 0; } Each process stores its number here when it gets the lock Processes indicate an interest in entering their shared region by calling this function. The parameter is either process 1 or 0 All values initially zero Process calls this function when it leaves its critical region.

Process 0 Process 1 Process 0 calls enter_region(0) lock 0 interested[0] 0 interested[1] 0

Process 0 Process 1 lock 0 interested[0] 0 interested[1] 0 other ? void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); }

Process 0 Process 1 lock 0 interested[0] 0 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; // if I’m 0 the other process is 1 interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other 1

Process 0 Process 1 lock 0 interested[0] 1 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; // Mark me as interested lock = process; while (lock == process && interested[other] == 1); } other 1 Note: Once process 0 has set interested[0] to 1, process 1 cannot enter its critical region!

Process 0 Process 1 lock 0 interested[0] 1 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; // give me the lock while (lock == process && interested[other] == 1); } other 1

Process 0 Process 1 Since interested[1] = 0, the while executes once and the function exits immediately. Process 0 is now in its critical region. lock 0 interested[0] 1 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other 1 Note: if process 1 were in its critical region, interested[1] would be 1 and process 0 would be blocked from entering its critical region.

Process 0 Process 1 Process 1 calls enter_region(1) lock 0 interested[0] 1 interested[1] 0

Process 0 Process 1 lock 0 interested[0] 1 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other ?

Process 0 Process 1 lock 0 interested[0] 1 interested[1] 0 void enter_region(int process) { int other; other = 1 – process; // I’m 1 so other is 0 interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other 0 0

Process 0 Process 1 lock 0 interested[0] 1 interested[1] 1 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; // mark me as interested lock = process; while (lock == process && interested[other] == 1); } other 0 0

Process 0 Process 1 lock 1 interested[0] 1 interested[1] 1 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; // give me the lock while (lock == process && interested[other] == 1); } other 0

Process 0 Process 1 The process stays in this loop until interested[0] changes to 0. lock 1 interested[0] 1 interested[1] 1 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other 0

Process 0 Process 1 Process 0 calls leave_region(0) lock 1 interested[0] 0 interested[1] 1 void leave_region(int process) { interested[process] = 0; }

Process 0 Process 1 Process 1 drops through the loop and exits. It now is in its critical region. lock 1 interested[0] 0 interested[1] 1 void enter_region(int process) { int other; other = 1 – process; interested[process] = 1; lock = process; while (lock == process && interested[other] == 1); } other 0

The TSL Instruction Many computers have an instruction of the form tsl rx, lock The instruction does two things: * It stores the current value of lock in the register rx * It stores a non-zero value in lock The key is that this instruction is guaranteed to be atomic, that is, no other instruction can be executed until both parts of the instruction are done.

Consider the following code in assembly language. The lock must be zero to enter the critical section: enter_region: tsl r1, lock cmp r1, #0 jne enter_region ret leave_region: move lock, #0 ret stores current value of lock in r1 and a non-zero value in lock test to see if original value of lock was zero, Loop back to beginning of loop if not. If it is zero, drop out of the loop and return. The lock is now non-zero. set the value of lock to 0

Both Petersen’s Solution and the TSL instruction work, … but require busy waiting. * Wasteful of CPU time * Priority Inversion Problem

Process H Process L Priority Inversion Problem Process H has high priority. The scheduling algorithm guarantees that it will always be run next if it is in a ready state.

Process H Process L Process H blocks, waiting for some I/O.

Process H Process L Process L now gets the cpu. It enters it’s critical region.

Process H Process L I/O completes and process H unblocks

Process H Process L Process H tries to enter its critical region. It calls enter_region and loops until lock is set to 0 by Process L

Process H Process L Because process H has a high priority, it gets all of the cpu time. It continues to loop, waiting for the lock to turn to 0. Process L, because it has a low priority, never gets any cpu time it and so never exits its critical region. The lock never clears.

Consumer-Producer Problems Fixed Size (bounded) buffer Producer Consumer Consumer-Producer problems are very common in system code.

Fixed Size buffer Producer Consumer The producer blocks if the buffer is full The consumer blocks if the buffer is empty. count A count is required so each can test the buffer condition.

Fixed Size buffer Producer Consumer if count == 0 block else remove item and decrement count if producer is asleep (blocked) wake producer if count == max block else add item and increment count if consumer is asleep (blocked) wake consumer count

Race Condition Fixed Size buffer Producer Consumer if count == 0 block else remove item and decrement count if producer is asleep wake producer if count == max block else add item and increment count if consumer is asleep wake consumer 0 1 The consumer does not get a chance to block. It gets swapped out.

Fixed Size buffer Producer Consumer if count == 0 block else remove item & decrement count if producer is asleep wake producer if count == max block else add item & increment count if consumer is asleep wake consumer 1 Since count was == 0, the producer thinks that the consumer is asleep, so it sends a wake up signal.

Fixed Size buffer Producer Consumer if count == 0 block else remove item and decrement count if producer is asleep wake producer if count == max block else add item and increment count if consumer is asleep wake consumer 1 The consumer is not really asleep. It has just been swapped out. Therefore, the wake-up signal is ignored. W a k e U p ! !

Fixed Size buffer Producer Consumer if count == 0 block else remove item & decrement count if producer is asleep wake producer if count == max block else add item & increment count if consumer is asleep wake consumer 1 The consumer is swapped into memory. The next instruction blocks. Now it waits for a wake up call.

Fixed Size buffer Producer Consumer if count == 0 block else remove item & decrement count if producer is asleep wake producer if count == max block else add item & increment count if consumer is asleep wake consumer 2 The next time the producer gets a time slice it stores a new element in the buffer. It thinks that the consumer is awake (count is non-zero), so no wake-up signal is ever sent.

Fixed Size buffer Producer Consumer if count == 0 block else remove item & decrement count if producer is asleep wake producer if count == max block else add item & increment count if consumer is asleep wake consumer max Eventually the buffer fills. The producer blocks. There is no way to wake the consumer. The program stops running.

Fixed Size buffer Producer Consumer if count == 0 block else remove item & decrement count if producer is asleep wake producer if count == max block else add item & increment count if consumer is asleep wake consumer max We need another mechanism to synchronize the Producer and the Consumer!

SemaphoresSemaphores The notion of semaphores was introduced in 1965 By E. W. Dijkstra.

Semaphores are a programming construct designed by E. W. Dijkstra in Dijkstra's model was the operation of railroads: consider a stretch of railroad in which there is a single track over which only one train at a time is allowed. Guarding this track is a semaphore. A train must wait before entering the single track until the semaphore is in a state that permits travel. When the train enters the track, the semaphore changes state to prevent other trains from entering the track. A train that is leaving this section of track must again change the state of the semaphore to allow another train to enter.

Counting Semaphore: Its values can range from 0 to some positive number Binary Semaphore: Its values are 1 and 0 Solve critical section problems with multiple processes These are sometimes called mutexes. Solve producer-consumer problems

Semaphores have two operations: down if value > 0 decrement semaphore else block An Atomic Operation! up increment semaphore if a blocked process is waiting wake the process An Atomic Operation! (wait) (signal)

How could we use counting semaphores to solve the producer-consumer problem?

Producer slots.down() // add item items.up() Consumer semaphore slots semaphore items items.down() // remove item slots.up() See the Unix Synchronization slides (slideSet20.ppt) for producer-consumer code written with Unix semaphores. Value is number of empty slots available in the buffer Value is number of items in the buffer Will block if no empty slots are available Wakes up the producer if the producer is blocked

MutexesMutexes Binary Semaphores are also known as Mutexes. When the semaphore’s ability to count is not needed, a mutex can be used. A mutex is a variable that can be in one of two states: locked and unlocked.

Next Time.... Using semaphores and mutexes in Unix!