Sistemi in tempo reale

Similar documents
Sistemi in tempo reale Anno accademico

Concurrent Programming I. Anna Lina Ruscelli Scuola Superiore Sant Anna

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

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

CSC 1600: Chapter 6. Synchronizing Threads. Semaphores " Review: Multi-Threaded Processes"

Pre-lab #2 tutorial. ECE 254 Operating Systems and Systems Programming. May 24, 2012

Concurrent Programming III: message passing, deadlock, livelock. Anna Lina Ruscelli Scuola Superiore Sant Anna

CS3502 OPERATING SYSTEMS

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

Data Races and Deadlocks! (or The Dangers of Threading) CS449 Fall 2017

Programming RT systems with pthreads

Semaphores. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Semaphores. A semaphore is an object that consists of a. methods (e.g., functions): signal and wait. semaphore. method signal. counter.

Programming RT systems with pthreads

Week 3. Locks & Semaphores

CS 25200: Systems Programming. Lecture 26: Classic Synchronization Problems

Synchronization: Advanced

Note: The following (with modifications) is adapted from Silberschatz (our course textbook), Project: Producer-Consumer Problem.

CS-345 Operating Systems. Tutorial 2: Grocer-Client Threads, Shared Memory, Synchronization

CS 345 Operating Systems. Tutorial 2: Treasure Room Simulation Threads, Shared Memory, Synchronization

Last Class: Synchronization

Synchroniza+on II COMS W4118

Process Synchronization

CS153: Midterm (Fall 16)

Achieving Synchronization or How to Build a Semaphore

High Performance Computing Lecture 21. Matthew Jacob Indian Institute of Science

Concurrent Server Design Multiple- vs. Single-Thread

ENGR 3950U / CSCI 3020U UOIT, Fall 2012 Quiz on Process Synchronization SOLUTIONS

POSIX / System Programming

Condition Variables CS 241. Prof. Brighten Godfrey. March 16, University of Illinois

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

EE458 - Embedded Systems Lecture 8 Semaphores

Synchronization. Semaphores implementation

real time operating systems course

Synchronization. Dr. Yingwu Zhu

CSci 4061 Introduction to Operating Systems. Synchronization Basics: Locks

W4118 Operating Systems. Instructor: Junfeng Yang

Carnegie Mellon. Bryant and O Hallaron, Computer Systems: A Programmer s Perspective, Third Edition

Synchronization II. Today. ! Condition Variables! Semaphores! Monitors! and some classical problems Next time. ! Deadlocks

Synchronization: Basics

IT 540 Operating Systems ECE519 Advanced Operating Systems

Process Synchronization(2)

CS533 Concepts of Operating Systems. Jonathan Walpole

Synchronization: Basics

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

CS 153 Lab6. Kishore Kumar Pusukuri

CS370 Operating Systems

Process Synchronization(2)

CSC Systems Programming Fall Lecture - XIV Concurrent Programming. Tevfik Ko!ar. Louisiana State University. November 2nd, 2010

CMSC421: Principles of Operating Systems

Synchronising Threads

Process Synchronisation (contd.) Operating Systems. Autumn CS4023

CS 470 Spring Mike Lam, Professor. Semaphores and Conditions

Process Synchronization(2)

Operating Systems. Thread Synchronization Primitives. Thomas Ropars.

Chapter 6: Process Synchronization

Assignment #2. Problem 2.1: airplane synchronization

Concurrency. Chapter 5

CS 6400 Lecture 11 Name:

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

POSIX Threads. Paolo Burgio

C09: Process Synchronization

Synchronization Primitives

Lecture 8: September 30

COMP 3430 Robert Guderian

Announcements. Class feedback for mid-course evaluations Receive about survey to fill out until this Friday

Process Synchronization. studykorner.org

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

Concurrency: a crash course

CSE 120. Fall Lecture 6: Semaphores. Keith Marzullo

Example Threads. compile: gcc mythread.cc -o mythread -lpthread What is the output of this program? #include <pthread.h> #include <stdio.

Operating systems. Lecture 12

[537] Concurrency Bugs. Tyler Harter

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

Recitation 14: Proxy Lab Part 2

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

Chapter 5 Concurrency: Mutual Exclusion and Synchronization

Warm-up question (CS 261 review) What is the primary difference between processes and threads from a developer s perspective?

What's wrong with Semaphores?

Carnegie Mellon. Synchroniza+on : Introduc+on to Computer Systems Recita+on 14: November 25, Pra+k Shah (pcshah) Sec+on C

CS4961 Parallel Programming. Lecture 12: Advanced Synchronization (Pthreads) 10/4/11. Administrative. Mary Hall October 4, 2011

recap, what s the problem Locks and semaphores Total Store Order Peterson s algorithm Johan Montelius 0 0 a = 1 b = 1 read b read a

Learning Outcomes. Concurrency and Synchronisation. Textbook. Concurrency Example. Inter- Thread and Process Communication. Sections & 2.

An Introduction to Parallel Systems

CPSC/ECE 3220 Fall 2017 Exam Give the definition (note: not the roles) for an operating system as stated in the textbook. (2 pts.

Overview. POSIX signals. Generation of signals. Handling signals. Some predefined signals. Real-time Systems D0003E 3/3/2009

CSCI 447 Operating Systems Filip Jagodzinski

Locks and semaphores. Johan Montelius KTH

Threads need to synchronize their activities to effectively interact. This includes:

Concurrency and Synchronisation

Concurrency and Synchronisation

Lecture 5 Threads and Pthreads II

Synchronization II. q Condition Variables q Semaphores and monitors q Some classical problems q Next time: Deadlocks

Today. Threads review Sharing Mutual exclusion Semaphores

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

ANKARA UNIVERSITY COMPUTER ENGINEERING DEPARTMENT BLM334-COM334 PROJECT

CS 550 Operating Systems Spring Concurrency Semaphores, Condition Variables, Producer Consumer Problem

Plan. Demos. Next Project. CSCI [4 6]730 Operating Systems. Hardware Primitives. Process Synchronization Part II. Synchronization Part 2

Introduction to the C programming language

CS 153 Lab4 and 5. Kishore Kumar Pusukuri. Kishore Kumar Pusukuri CS 153 Lab4 and 5

Transcription:

Sistemi in tempo reale Semaphores Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa October 5, 2011

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

A general mechanism for blocking tasks The semaphore mechanism was first proposed by Dijkstra A semaphore is an abstract data type that consists of a counter a blocking queue operation wait operation signal The operations on a semaphore must be atomic the OS makes them atomic by appropriate low-level mechanisms

Semaphore definition semaphores are a basic mechanisms for providing synchronization it has been shown that every kind of synchronization and mutual exclusion can be implemented by using sempahores we will analyze possible implementation of the semaphore mechanism later class Semaphore { <blocked queue> blocked; int counter; public: Semaphore (int n) : count (n) {...} void wait(); void signal(); };

Wait and signal a wait operation has the following behavior:

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked;

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue;

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue; if counter > 0, then counter--;

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue; if counter > 0, then counter--; a signal operation has the following behavior:

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue; if counter > 0, then counter--; a signal operation has the following behavior: if counter == 0 and there is some blocked thread, unblock it;

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue; if counter > 0, then counter--; a signal operation has the following behavior: if counter == 0 and there is some blocked thread, unblock it; the thread is removed from the blocked queue and inserted in the ready queue

Wait and signal a wait operation has the following behavior: if counter == 0, the requiring thread is blocked; it is removed from the ready queue and inserted in the blocked queue; if counter > 0, then counter--; a signal operation has the following behavior: if counter == 0 and there is some blocked thread, unblock it; the thread is removed from the blocked queue and inserted in the ready queue otherwise, increment counter;

Pseudo-code for wait and signal class Semaphore { <blocked queue> blocked; int counter; public: Semaphore (int n) : counter (n) {...} void wait() { if (counter == 0) <block the thread> else counter--; } void signal() { if (<some blocked thread>) <unblock the thread> else counter++; } };

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

Mutual exclusion with semaphores To use a semaphore for mutual exclusions: define a semaphore initialized to 1 before entering the critical section, perform a wait after leaving the critical section, perform a signal void *threada(void *) {... s.wait(); <critical section> s.signal();... } void *threadb(void *) {... s.wait(); <critical section> s.signal();... }

Mutual exclusion: example Semaphore Counter 1 Blocked queue Ready queue TB TA

Mutual exclusion: example Semaphore Counter 0 Blocked queue example1.c s.wait(); (TA) Ready queue TB TA

Mutual exclusion: example Semaphore Counter 0 Blocked queue example1.c s.wait(); <critical section (1)> (TA) (TA) Ready queue TB TA

Mutual exclusion: example Semaphore Counter 0 Blocked queue example1.c s.wait(); <critical section (1)> s.wait(); (TA) (TA) (TB) Ready queue TA TB

Mutual exclusion: example Semaphore Counter 0 Blocked queue TB example1.c s.wait(); <critical section (1)> s.wait(); <critical section (2)> (TA) (TA) (TB) (TA) Ready queue TA

Mutual exclusion: example Semaphore Counter 0 Blocked queue TB example1.c s.wait(); <critical section (1)> s.wait(); <critical section (2)> s.signal(); (TA) (TA) (TB) (TA) (TA) Ready queue TA

Mutual exclusion: example Semaphore Counter 0 Blocked queue example1.c s.wait(); <critical section (1)> s.wait(); <critical section (2)> s.signal(); <critical section> (TA) (TA) (TB) (TA) (TA) (TB) Ready queue TA TB

Mutual exclusion: example Semaphore Counter 1 Blocked queue example1.c s.wait(); <critical section (1)> s.wait(); <critical section (2)> s.signal(); <critical section> s.signal(); (TA) (TA) (TB) (TA) (TA) (TB) (TB) Ready queue TA TB

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

Synchronization with semaphores How to use a semaphore for synchronizing two or more threads define a sempahore initialized to 0 at the syncronization point, the task to be blocked performs a wait at the synchronization point, the other task performs a signal Example: thread A must block if it arrives at the synch point before thread B Semaphore s(0); void *threada(void *) {... s.wait();... } void *threadb(void *) {... s.signal();... }

Problem 1 How to make each thread wait for the other one? The first one that arrives at the synchronization point waits for the other one.

Problem 1 How to make each thread wait for the other one? The first one that arrives at the synchronization point waits for the other one. Solution: use two semaphores! Semaphore sa(0), sb(0); void *threada(void *) {... sa.signal(); sb.wait();... } void *threadb(void *) {... sb.signal(); sa.wait();... }

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

Problem 2 Generalize the previous synchronization problem to N threads The first N-1 threads must block waiting for the last one

Problem 2 Generalize the previous synchronization problem to N threads The first N-1 threads must block waiting for the last one First solution (more elegant)

Problem 2 Generalize the previous synchronization problem to N threads The first N-1 threads must block waiting for the last one First solution (more elegant) Second solution (more practical)

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

Producer / Consumer We now want ot implement a mailbox with a circular array avoiding busy wait The producer must be blocked when the mailbox is full The consumer must be blocked when the mailbox is empty We use appropriate semaphores to block these threads Initially we consider only one producer and one consumer

Implementation circulararray1.c #define N 10 class CA { int array[n]; int head(0); int tail(0); Semaphore empty(0); Semaphore full(n); public: void insert(int elem); void extract(int &elem); }; circulararray1.c void CA::insert(int elem) { full.wait(); array[head++] = elem; head = head % N; empty.signal(); } void CA::extract(int &elem) { empty.wait(); elem = array[tail++]; tail = tail % N; full.signal(); }

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem;

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array;

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block;

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N;

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N; If the extract begins before the end of an insert, it will be blocked

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N; If the extract begins before the end of an insert, it will be blocked After an insert, there is an element in the queue, so we are in the previous case

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N; If the extract begins before the end of an insert, it will be blocked After an insert, there is an element in the queue, so we are in the previous case For symmetry, the same holds for the case of N elements in the queue. Again, head = tail, counter of empty = N, counter of full = 0;

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N; If the extract begins before the end of an insert, it will be blocked After an insert, there is an element in the queue, so we are in the previous case For symmetry, the same holds for the case of N elements in the queue. Again, head = tail, counter of empty = N, counter of full = 0; If the insert begins before the end of an extract, it will be blocked

Proof of correctness when the number of elements in the queue is between 1 and 9, there is no problem; insert and extract work on different variables (head and tail respectively) and different elements of the array; The value of full and empty is always greater than 0, so neither the producer nor the consumer can block; when there is no element in the queue, head = tail, counter of empty = 0, counter of full = N; If the extract begins before the end of an insert, it will be blocked After an insert, there is an element in the queue, so we are in the previous case For symmetry, the same holds for the case of N elements in the queue. Again, head = tail, counter of empty = N, counter of full = 0; If the insert begins before the end of an extract, it will be blocked After an extract, we fall back in the previous case

Multiple producers/consumers Suppose now there are mamy producers and many consumers; all producers will act on the same variable head, and all consumers on tail; If one producer preempts another producer, an inconsistency can arise Exercise: prove the above sentence Therefore, we need to combine synchronization and mutual exclusion

First solution circulararray-wrong.c #define N 10 class CA { int array[n]; int head(0); int tail(0); Semaphore empty(0); Semaphore full(n); Semaphore mutex(1); public: void insert(int elem); void extract(int &elem); }; circulararray-wrong.c void CA::insert(int elem) { mutex.wait(); full.wait(); array[head++] = elem; head = head % N; empty.signal(); mutex.signal(); } void CA::extract(int &elem) { mutex.wait(); empty.wait(); elem = array[tail++]; tail = tail % N; full.signal(); mutex.signal(); }

Wrong solution The previous solution is wrong! Counter example: A consumer thread executes first, locks the mutex and blocks on the empty semaphore All other threads (producers or consumers) will block on the mutex Lesson learned: never block inside a mutex!

Deadlock Deadlock situation A thread executes mutex.wait() and then blocks on a synchronisation semaphore To be unblocked another thread must enter a critical section guarded by the same mutex semaphore So, the first thread cannot be unblocked and free the mutex The situation cannot be solved

Correct solution circulararray-correct.c #define N 10 class CA { int array[n]; int head(0); int tail(0); Semaphore empty(0); Semaphore full(n); Semaphore mutex(1); public: void insert(int elem); void extract(int &elem); }; circulararray-correct.c void CA::insert(int elem) { full.wait(); mutex.wait(); array[head++] = elem; head = head % N; mutex.signal(); empty.signal(); } void CA::extract(int &elem) { empty.wait(); mutex.wait(); elem = array[tail++]; tail = tail % N; mutex.signal(); full.signal(); }

Exercises Solve the previous exercise with two mutex (one for the consumers and one for the producers) Prove the solution is correct Suppose there are one producer and N consumer. Every message has to be received by each consumer. Write the data structure, the insert and extract functions Suppose that extract() takes an additional arguments that specifies the consumer ID (between 0 and N-1).

Outline 1 Semaphores Mutual exclusion Synchronization Exercise Producer / Consumer 2 Solutions

First solution to problem 2 Elegant solution. Uses many semaphores! (with the pthread interface) prob2-solution1.c #include <stdio.h> #include <pthread.h> #include <semaphore.h> #define N 8 sem_t s[n][n]; void init() { int i, j; for (i=0; i<n; i++) for(j=0; j<n; j++) sem_init(&s[i][j], 0, 0); } prob2-solution1.c int main() { pthread_t tid[n]; int i; int args[n]; init(); for (i=0; i<n; i++) { args[i] = i; pthread_create(&tid[i], 0, thread, (void *)&args[i]); } void *thread(void *arg) { int k = *((int *) arg); int j; printf("th%d: before synch\n", k); for (j=0; j<n; j++) if (j!=k) sem_post(&s[k][j]); for (j=0; j<n; j++) if (j!=k) sem_wait(&s[j][k]); printf("th%d: after synch\n", k); return 0; }

Second solution to problem 2 Practical solution. We need a mutex semaphore, a counter, and a semaphore to block threads. (with the pthread interface) solution2.c solution2.c struct synch { int count; sem_t m; // mutex sem_t b; // blocked int N; // number of threads }; void initsynch(struct synch *s, int n) { int i; s->count = 0; sem_init(&s->m, 0, 1); sem_init(&s->b, 0, 0); s->n = n; } void my_synch(struct synch *s) { int i; sem_wait(&s->m); if (++s->count < s->n) { sem_post(&s->m); sem_wait(&s->b); } else { for (i=0; i < s->n - 1; i++) sem_post(&s->b); sem_post(&s->m); } } struct synch sp; void *thread(void *arg) {... mysynch(&sp);... }