CSCI 447 Operating Systems Filip Jagodzinski

Similar documents
CSCI 447 Operating Systems Filip Jagodzinski

Deadlock and Monitors. CS439: Principles of Computer Systems February 7, 2018

Lecture 8: September 30

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

Introduction to OS Synchronization MOS 2.3

Chapter 6: Synchronization. Operating System Concepts 8 th Edition,

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

Deadlock and Monitors. CS439: Principles of Computer Systems September 24, 2018

Chapter 7: Process Synchronization!

2.c Concurrency Mutual exclusion & synchronization mutexes. Unbounded buffer, 1 producer, N consumers

Process/Thread Synchronization

CS4411 Intro. to Operating Systems Exam 1 Fall points 10 pages

Background. The Critical-Section Problem Synchronisation Hardware Inefficient Spinning Semaphores Semaphore Examples Scheduling.

Chapter 6: Process Synchronization

Chapter 6: Process Synchronization

CS370 Operating Systems

Synchronization. Before We Begin. Synchronization. Credit/Debit Problem: Race Condition. CSE 120: Principles of Operating Systems.

Chapter 6: Process Synchronization. Operating System Concepts 8 th Edition,

Operating Systems ECE344

Process Synchronization

EECS 482 Introduction to Operating Systems

Chapters 5 and 6 Concurrency

Chapter 5: Process Synchronization. Operating System Concepts Essentials 2 nd Edition

G52CON: Concepts of Concurrency

Process Synchronisation (contd.) Deadlock. Operating Systems. Spring CS5212

Chapter 6: Synchronization. Chapter 6: Synchronization. 6.1 Background. Part Three - Process Coordination. Consumer. Producer. 6.

PESIT Bangalore South Campus

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

SWEN-220 Mathematical Models of Software. Process Synchronization Critical Section & Semaphores

Background. Old Producer Process Code. Improving the Bounded Buffer. Old Consumer Process Code

Semaphores. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Process/Thread Synchronization

Process Synchronization

Synchronization. Race Condition. The Critical-Section Problem Solution. The Synchronization Problem. Typical Process P i. Peterson s Solution

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Process Synchronization. Mehdi Kargahi School of ECE University of Tehran Spring 2008

Synchronization. Before We Begin. Synchronization. Example of a Race Condition. CSE 120: Principles of Operating Systems. Lecture 4.

Last Class: Synchronization. Review. Semaphores. Today: Semaphores. MLFQ CPU scheduler. What is test & set?

Opera&ng Systems ECE344

Synchronization Principles

What is the Race Condition? And what is its solution? What is a critical section? And what is the critical section problem?

Lecture. DM510 - Operating Systems, Weekly Notes, Week 11/12, 2018

The University of Texas at Arlington

Synchronization Spinlocks - Semaphores

KING FAHD UNIVERSITY OF PETROLEUM & MINERALS. Information and Computer Science Department. ICS 431 Operating Systems. Lab # 9.

CSE 120: Principles of Operating Systems. Lecture 4. Synchronization. October 7, Prof. Joe Pasquale

CS 153 Design of Operating Systems Winter 2016

Lesson 6: Process Synchronization

Interprocess Communication By: Kaushik Vaghani

Synchronization Principles I

Threading and Synchronization. Fahd Albinali

IT 540 Operating Systems ECE519 Advanced Operating Systems

PROCESS SYNCHRONIZATION

COMP 3430 Robert Guderian

The University of Texas at Arlington

UNIX Input/Output Buffering

CS420: Operating Systems. Process Synchronization

CMSC421: Principles of Operating Systems

Last Class: Deadlocks. Today

Process Synchronization

Process Synchronization(2)

Concurrency: a crash course

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Recap: Thread. What is it? What does it need (thread private)? What for? How to implement? Independent flow of control. Stack

CSE 120. Fall Lecture 6: Semaphores. Keith Marzullo

Homework Assignment #5

Operating Systems. Designed and Presented by Dr. Ayman Elshenawy Elsefy

CS370 Operating Systems

CS 333 Introduction to Operating Systems. Class 4 Concurrent Programming and Synchronization Primitives

CS3502 OPERATING SYSTEMS

Midterm on next week Tuesday May 4. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 9

CS 31: Intro to Systems Misc. Threading. Kevin Webb Swarthmore College December 6, 2018

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

Concurrency and Synchronisation

Process Synchronization (Part I)

Dealing with Issues for Interprocess Communication

Process Synchronization

Threads and Synchronization. Kevin Webb Swarthmore College February 15, 2018

Puzzle: Write synchronization code for oxygen and hydrogen molecules that enforces these constraints.

CS 162 Operating Systems and Systems Programming Professor: Anthony D. Joseph Spring Lecture 8: Semaphores, Monitors, & Condition Variables

Programming Languages

CS 31: Introduction to Computer Systems : Threads & Synchronization April 16-18, 2019

Process Synchronization

Programming Languages

Chapter 7: Process Synchronization. Background. Illustration

Introduction to Operating Systems

Operating Systems CMPSCI 377 Spring Mark Corner University of Massachusetts Amherst

More Types of Synchronization 11/29/16

IV. Process Synchronisation

Announcements. Office hours. Reading. W office hour will be not starting next week. Chapter 7 (this whole week) CMSC 412 S02 (lect 7)

Process Management And Synchronization

Synchronization. CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Process Synchronization: Semaphores. CSSE 332 Operating Systems Rose-Hulman Institute of Technology

MULTITHREADING AND SYNCHRONIZATION. CS124 Operating Systems Fall , Lecture 10

Chapter 5 Concurrency: Mutual Exclusion and Synchronization

CSE Traditional Operating Systems deal with typical system software designed to be:

Concurrency and Synchronisation

CS11 Java. Fall Lecture 7

Classical concurrency control: topic overview 1 In these lectures we consider shared writeable data in main memory

CS Operating Systems

Transcription:

Filip Jagodzinski

Announcements Homework 2 you have 2 weeks start now Book questions including two custom ones A single programming task File names and directories, class conventions homework2-script, or homework2-script.txt lab2-script, or lab2-script.txt

Announcements Homework 2 you have 2 weeks start now Book questions including two custom ones A single programming task File names and directories, class conventions homework2-script, or homework2-script.txt lab2-script, or lab2-script.txt Git (any repo) conventions Do not push.o or executables to a git repo why? Use.gitignore or add files one-by-one (Example shown right) file :.gitignore *.o *.exe *.pdf

Review Asynchronous cancellation Deferred cancellation A thread immediately terminates the target thread The target thread periodically checks in to find out if it should be terminated; if so, does it in an orderly fashion

Review Asynchronous cancellation Deferred cancellation A thread immediately terminates the target thread The target thread periodically checks in to find out if it should be terminated; if so, does it in an orderly fashion Q: Why might asynchronous thread cancellation be problematic? buffer thread 1 thread 2

Review Thread B i1: count = count + 1 i2: count = count - 1

Review Thread B i1: count = count + 1 i2: count = count - 1 a1: load count a2: add 1 a3: store count Register/ALU view b1: load count b2: subtract 1 b3: store count

Review Thread B i1: count = count + 1 i2: count = count - 1 a1: load count a2: add 1 a3: store count Register/ALU view b1: load count b2: subtract 1 b3: store count Assume initial value of count = 4 a1 < b1 < a2 < a3 < b2 < b3 count = 3 a1 < a2 < a3 < b1 < b2 < b3 count = 4 a1 < a2 < b1 < b2 < b3 < a3 count = 5 b1 < b2 < a1 < b3 < a2 < a3 count = 5

Review Peterson s Solution do { flag[i] = true; turn = j; while (flag[j] && turn == j){}; Critical section flag[i] = false // other stuff (remainder) } while(true); Works for 2 processes/threads j = 1-i; Requires additional (shared) data : int turn; boolean flag[2]; Process i sets flag[i] to true (to specify, hey, I m ready to entry my critical section ) A process sets turn to j (the other process) If both processes try to enter their critical section, although flag might be [1,1], because turn is a single shared value, only one of the processes will succeed in setting turn to the other process.

Review Most operating systems allow, via a system call, the use of a mutex this allows the application programmer to solve a critical section problem Mutex : Mutual Exclusion This high level idea is the following : have the OS provide system calls for a lock that can be used to control access to a critical section. do { // acquire lock Critical section acquire(){ while(!available) {}; available = false } // release lock // other stuff (remainder) } while(true); release(){ available = true } available, in this implementation, is the variable that is used to specify whether a process is in its critical section

In-class exercise

Review A solution to the critical section problem must satisfy 3 criteria Mutual exclusion : if a process is executing its critical section, no other process can be executing its critical section Progress : If no process is executing its critical section, AND some process wants to enter its critical section, then only those processes NOT executing code in their other sections can decide who enters Bounded Waiting : there must be a limit on the number of times that ANOTHER process is allowed to enter its critical section after a process has made a request to enter its critical section

Today Chapter 5 s Deadlock

Synchronization When more than 1 thread is running, synchronization is important Some terminology, assuming two events : Serialization : Event A must happen before? Event B Mutual Exclusion : Events A and B must NOT happen? at the same time Concurrent :?

Synchronization When more than 1 thread is running, synchronization is important Some terminology, assuming two events : Serialization : Event A must happen before Event B Mutual Exclusion : Events A and B must NOT happen? at the same time Concurrent :?

Synchronization When more than 1 thread is running, synchronization is important Some terminology, assuming two events : Serialization : Event A must happen before Event B Mutual Exclusion : Events A and B must NOT happen at the same time Concurrent :?

Synchronization When more than 1 thread is running, synchronization is important Some terminology, assuming two events : Serialization : Event A must happen before Event B Mutual Exclusion : Events A and B must NOT happen at the same time Concurrent : More than 1 thread making progress... it is not possible to know a priori what instruction history will be realized

Instruction Execution Q: How might you enforce a certain order of instruction execution?

Instruction Execution Q: How might you enforce a certain order of instruction execution?

Instruction Execution A1 A2 A3 Thread M M1 M2 M3 Q: What are the possible orderings, histories, of A1-A3 and M1-M3 if threads A and M are run concurrently? Q: How many unique execution histories are there in this scenario?

Instruction Execution A1 A2 A3 Thread M M1 M2 M3 What if only one the below two execution histories were acceptable Desired execution order : A1 < A2 < M1 < M2 < M3 < A3 Desired execution order : A1 < M1 < A2 < M2 < M3 < A3 Q: How would you impose these orders using sleep?

Instruction Execution A1 A2 A3 Thread M M1 M2 M3 What if only one the below two execution histories were acceptable Desired execution order : A1 < A2 < M1 < M2 < M3 < A3 Desired execution order : A1 < M1 < A2 < M2 < M3 < A3 Q: Is using sleep() a practical solution?

Instruction Execution Q: How is it done in the real world?

Instruction Execution Q: How is it done in the real world? A is a data structure that permits threads to coordinate among each other and specify which thread(s) wait and which thread(s) execute. Invented by Edsger Dijkstra (for CS applications) semaphore : a system of sending messages

s A data structure that contains only a single non-negative integer as a datum int value

s A data structure that contains only a single non-negative integer as a datum The integer can be initialized to any nonnegative value, but once declared and set, it is modified only by several methods (there are no direct setter and getter methods) int value Q: Why are there no setter and getter methods for semaphores?

s A data structure that contains only a single non-negative integer as a datum The integer can be initialized to any nonnegative value, but once declared and set, it is modified only by several methods (there are no direct setter and getter methods) Operation 1 : increment Operation 2 : decrement int value + (int) + increment + decrement

s A data structure that contains only a single non-negative integer as a datum The integer can be initialized to any nonnegative value, but once declared and set, it is modified only by several methods (there are no direct setter and getter methods) Operation 1 : increment Operation 2 : decrement The method is the constructor; it creates and returns a reference variable to a new int value + (int) + increment + decrement

s A data structure that contains only a single non-negative integer as a datum The integer can be initialized to any nonnegative value, but once declared and set, it is modified only by several methods (there are no direct setter and getter methods) Operation 1 : increment Operation 2 : decrement The method is the constructor; it creates and returns a reference variable to a new int value + (int) + increment + decrement Q: Now that we have the structure, what is the behavior of the? Or, how is it used?

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore int value + (int) + increment + decrement

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore int value + (int) + increment + decrement Thread notifies the scheduler that it cannot proceed. Scheduler will prevent the thread from running until an event occurs that causes the thread to become unblocked

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement Sometimes referred to as waking

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement Q: Which thread is executed after a shared s value is incremented?

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement Q: Which thread is executed after a shared s value is incremented? A: Both the thread that is unblocked AND the thread that issued the increment are scheduled concurrently... Q: In which order?

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement When a thread signals a, it has no knowledge of how many other threads (if any) are waiting

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement The nuances of semaphores results in several unique use scenarios

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement The nuances of semaphores results in several unique use scenarios Incrementing may affect other threads Decrementing directly affects only the thread that issued the call

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement The nuances of semaphores results in several unique use scenarios Incrementing is often referred to as signal() Decrementing is often referred to as wait()

s If decrement would result in the datum being negative, then the thread that issued the decrement will be blocked and will not continue until ANOTHER thread increments the semaphore If increment occurs, an already waiting thread is unblocked. int value + (int) + increment + decrement Increment and decrement refer to what a DOES (to the value) Signal and Wait describe what they are USED FOR Dijkstra, because of this confusion referred to increment as V, and decrement as P use a meaningless name rather than a confusing one

s The data structure shown right is the user (software) view. int value + (int) + increment + decrement

s The data structure shown right is the user (software) view. When a semaphore is created by the OS, the object has additional information there is needed a list of processes/threads that have invoked the decrement method, and which are blocked typedef struct{ int value; struct process *list; } semaphore int value + (int) + increment + decrement int value - process *list + increment + decrement

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement()

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement() Task : Draw the variable, object reference diagram that results after this line of code is executed

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement() asem value = 3

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement() asem value = 4 Q: When asem s value is incremented from 3 to to 4, what effect does that have on?

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement() asem value = 4 Q: When asem s value is incremented from 3 to to 4, what effect does that have on? Q: When asem s value is incremented to 4, what effect does that have on other threads?

s Syntax is straight-forward but it is OS specific, so the pseudocode description is used in most textbooks asem = (3) asem.increment() asem.decrement() asem value = 3 Q: When asem s value is incremented from 3 to to 4, what effect does that have on? Q: When asem s value is incremented to 4, what effect does that have on other threads? Q: When asem s value is decremented from 4 to 3, what effect does that have on and on other threads?

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) Q: What is achieved when the code in the yellow box is executed?

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 0

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 0 Q: What is achieved when the code in the yellow box is executed?

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 1

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 1 Q: What is achieved when the code in the yellow box is executed?

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 0

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 0 Q: What is achieved when the code in the yellow box is executed?

s Another example mysem = (0) mysem.increment() mysem.decrement() mysem.decrement() mysem.decrement() print( hello ) mysem value = 0 self stalls is the last decrement executed? Is the print statement executed?

s s are used to halt a thread and to enforce running one thread in a specific sequence relative to another

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) In-class exercise 1 Thread B a1 b1

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Task : Explain via prose how to use a semaphore(s) to attain this goal Thread B a1 b1

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) Thread B a1 b1

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 Task : Be able to explain why the above use of the ensures the goal

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 Q: Does the use of the by the two threads guarantee that will complete prior to Thread B starting?

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 We do not know how the OS will schedule the two threads. Q: What are the scheduling choices?

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 Choice 1 : < Thread B Choice 2 : Thread B < Task : Be sure you understand both execution orders

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 Choice 1 : < Thread B Choice 2 : Thread B < Q: What Is the sequence of events when Thread A is scheduled to execute first? (on the board walk through)

s Assume a1 writes to a file, and b1 prints a line from the file (hence reads from the file) Goal : We want a1 to complete before b1 begins Already run code sem = (0) a1 sem.increment() Thread B sem.decrement() b1 Choice 1 : < Thread B Choice 2 : Thread B < Q: What Is the sequence of events when Thread B is scheduled to execute first? (on the board walk through)

s In-class exercise 2 a1 a2 Thread B b1 b2 Goals a1 must happen before b2 b1 must happen before a2

s Sample solution (in class) Already run code Thread B a1 b1 a2 b2 Goals a1 must happen before b2 b1 must happen before a2

s Sample solution (in class) Already run code Thread B a1 b1 a2 b2 Goals a1 must happen before b2 b1 must happen before a2 Q : How many unique solutions are there? Q : What is the fewest number of semaphores needed?

Deadlock sem1 = (0) sem2 = (0) a1 sem1.increment() sem2.decrement() a2 Thread B b1 sem2.increment() sem1.decrement() b2 0 0 We saw that the above use of two semaphores enforced that a1 happen before b2, and b1 happen before a2 Q: Is use of semaphores always safe?

Deadlock Thread B sem1 = (0) sem2 = (0) a1 a2 b1 b2 0 0 We saw that the above use of two semaphores enforced that a1 happen before b2, and b1 happen before a2 Q: Is use of semaphores always safe? Task : Add method calls to sem1 and sem2 such that and Thread B do not execute to completion.

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first?

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1 sem1 -> -1 (attempt, A self blocks)

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1 sem1 -> -1 (attempt, A self blocks) b1

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1 sem1 -> -1 (attempt, A self blocks) b1 sem2 -> -1 (attempt, B self blocks)

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1 sem1 -> -1 (attempt, A self blocks) b1 sem2 -> -1 (attempt, B self blocks) Q: At this point what happens?

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 < Thread B Q: What is the result of the execution of the two Threads, assuming A is scheduled first? a1 sem1 -> -1 (attempt, A self blocks) b1 sem2 -> -1 (attempt, B self blocks) Deadlock

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 Thread B < Q: What is the result of the execution of the two Threads, assuming B is scheduled first?

Deadlock sem1 = (0) sem2 = (0) a1 sem1.decrement() sem2.increment() a2 Thread B b1 sem2.decrement() sem1.increment() b2 0 0 Thread B < Q: What is the result of the execution of the two Threads, assuming B is scheduled first? Also a Deadlock

Mutex Thread B count = count + 1 count = count +1 Add semaphores to the above two threads to enforce mutual exclusion to the shared variable count Hint : This can be implemented with a single semaphore Unlike previously, we don t care which of the two threads is scheduled first Further assume that we do NOT want to decompose the above 2 instructions into fetch, update, and WB steps

Mutex mutex = (1) mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() Assume the above decrement and increment invocations are placed among 2 threads, and B, run concurrently. Q: What value should the semaphore mutex be initialized to so that its use solves the critical section problem for Threads A and B? A : -1 B : 0 C : 1 D : 2

Mutex mutex = (1) 1 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() Q: What are the possible sequences of scheduling/execution?

Mutex mutex = (1) 1 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Q: What are the possible sequences of scheduling/execution? Thread B <

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 Q: Does this self-block A?

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 Q: Because of duplicated pipelines, threading, etc., and Thread B are being executed concurrently at this point, what happens if B for some reason is scheduled?

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 B decrements : mutex -> -1 (attempt, blocks)

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 B decrements : mutex -> -1 (attempt, blocks) A updates count

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 B decrements : mutex -> -1 (attempt, blocks) A updates count A increments : mutex -> 0 (B unblocked)

Mutex mutex = (1) 0 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 B decrements : mutex -> -1 (attempt, blocks) A updates count A increments : mutex -> 0 (B unblocked) B updates count

Mutex mutex = (1) 1 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < A decrements : mutex -> 0 B decrements : mutex -> -1 (self blocks) A updates count A increments : mutex -> 0 (B unblocked) B updates count B increments : mutex -> 1

Mutex mutex = (1) 1 mutex.decrement() count = count + 1 mutex.increment() Thread B mutex.decrement() count = count +1 mutex.increment() < Thread B Thread B < Task : Be able to step through the same code for the other sequence

Mutex Q: What is the utility of using semaphores to impose mutex versus the use of Peterson s solution? Q: Does the use of semaphores satisfy all of the conditions needed for a solution to the critical section problem?

Mutex Thread B Thread C count = count + 1 count = count +1 count = count +1 Q: What is the minimum number of semaphores needed to enforce mutual exclusion among these three threads, and what should the semaphore(s) be initialized to? A : A single semaphore, initialized to 0 B : Two semaphores, both initialized to 0 C : Three semaphores, each initialized to 0 D : None of the above

Mutex mutex.wait() count = count + 1 mutex.signal() Thread B mutex.wait() count = count +1 mutex.signal() Thread C mutex.wait() count = count +1 mutex.signal() Q: What is the minimum number of semaphores needed to enforce mutual exclusion among these three threads, and what should the semaphore(s) be initialized to? A : A single semaphore, initialized to 0 B : Two semaphores, both initialized to 0 C : Three semaphores, each initialized to 0 D : None of the above A single semaphore, initialized to 1

Multiplex Q: What is one functional purpose for initializing a semaphore to a non-zero value when 1, 2, 3, or n threads use that semaphore? a = (8) 8

Multiplex Thread B x = x + 1 x = x - 12 Thread C x = 4 Create one or more semaphores and invoke the wait and signal methods among Threads A-C to enforce an upper limit of 2 for the number of threads that can access concurrently the shared variable x

Multiplex multiplex = (2) 2 multiplex.dec() x = x + 1 multiplex.inc() Thread B multiplex.dec() x = x 12 multiplex.inc() Thread C multiplex.dec() x = 4 multiplex.inc() Q: How many possible choices are there of scheduling the 3 Threads?

Multiplex multiplex = (2) 2 multiplex.dec() x = x + 1 multiplex.inc() Thread B multiplex.dec() x = x 12 multiplex.inc() Thread C multiplex.dec() x = 4 multiplex.inc() Q: How many possible choices are there of scheduling the 3 Threads? < Thread B < Thread C < Thread C < Thread B Thread B < < Thread C Thread B < Thread C < Thread C < < Thread B Thread C < Thread B <

Multiplex multiplex = (2) 2 multiplex.dec() x = x + 1 multiplex.inc() Thread B multiplex.dec() x = x 12 multiplex.inc() Thread C multiplex.dec() x = 4 multiplex.inc() Q: How many possible choices are there of scheduling the 3 Threads? < Thread B < Thread C < Thread C < Thread B Thread B < < Thread C Thread B < Thread C < Thread C < < Thread B Thread C < Thread B < Regardless of the scheduling, only 2 Threads at any one time may access the code that updates the value of x.

Up Next Implementation of Mutex using blitz Chapter 5 : Monitors Chapter 6 : Scheduling