Locks and semaphores. Johan Montelius KTH

Similar documents
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

Locks and semaphores. Johan Montelius KTH

Multithreading Programming II

Synchronization and Semaphores. Copyright : University of Illinois CS 241 Staff 1

What is concurrency? Concurrency. What is parallelism? concurrency vs parallelism. Concurrency: (the illusion of) happening at the same time.

POSIX Threads. Paolo Burgio

real time operating systems course

Concurrency. Johan Montelius KTH

Operating System Labs. Yuanbin Wu

Synchronization Mechanisms

CS 153 Lab6. Kishore Kumar Pusukuri

Synchronization Primitives

Synchronization and Semaphores. Copyright : University of Illinois CS 241 Staff 1

Synchronization I. To do

Synchronization I. Today. Next time. Race condition, critical regions and locks. Condition variables, semaphores and Monitors

Synchroniza+on II COMS W4118

1 Introduction. 2 total-store-order. Take me for a spin. 2.1 Peterson's algorithm. Johan Montelius HT2016

CSci 4061 Introduction to Operating Systems. Synchronization Basics: Locks

Synchronization I. Today. Next time. Monitors. ! Race condition, critical regions and locks. ! Condition variables, semaphores and

Locks. Dongkun Shin, SKKU

Real Time Operating Systems and Middleware

Introduction to parallel computing

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

Week 3. Locks & Semaphores

Process Synchronization (Part I)

W4118 Operating Systems. Instructor: Junfeng Yang

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

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

Resource Access Control (2) Real-Time and Embedded Systems (M) Lecture 14

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

Synchronising Threads

Condition Variables. Dongkun Shin, SKKU

Process Synchronization(2)

Lecture 9: Thread Synchronizations. Spring 2016 Jason Tang

The course that gives CMU its Zip! Concurrency II: Synchronization Nov 14, 2000

Process Synchronization(2)

TCSS 422: OPERATING SYSTEMS

CS 470 Spring Mike Lam, Professor. Semaphores and Conditions

Thread and Synchronization

Implementing Locks. Nima Honarmand (Based on slides by Prof. Andrea Arpaci-Dusseau)

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

Operating Systems. Lecture 4 - Concurrency and Synchronization. Master of Computer Science PUF - Hồ Chí Minh 2016/2017

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

Process Synchronization(2)

CSE 4/521 Introduction to Operating Systems

[537] Locks and Condition Variables. Tyler Harter

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

Process Synchronization. studykorner.org

Faculté Polytechnique

Condition Variables. Dongkun Shin, SKKU

Multithread Programming. Alexandre David

Threads. Jo, Heeseung

Concurrency, Thread. Dongkun Shin, SKKU

Final Examination (Fall 2016) (Section 1)

Solving the Producer Consumer Problem with PThreads

Thread. Disclaimer: some slides are adopted from the book authors slides with permission 1

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

Network Programming TDC 561

Paralleland Distributed Programming. Concurrency

Introduction to PThreads and Basic Synchronization

Ricardo Rocha. Department of Computer Science Faculty of Sciences University of Porto

Synchronization. Disclaimer: some slides are adopted from the book authors slides with permission 1

POSIX Threads. HUJI Spring 2011

CSCE 313: Introduction to Computer Systems

Operating Systems. Thread Synchronization Primitives. Thomas Ropars.

CMSC421: Principles of Operating Systems

CS 220: Introduction to Parallel Computing. Condition Variables. Lecture 24

Lecture 4. Threads vs. Processes. fork() Threads. Pthreads. Threads in C. Thread Programming January 21, 2005

CS533 Concepts of Operating Systems. Jonathan Walpole

Condition Variables & Semaphores

Semaphore. Originally called P() and V() wait (S) { while S <= 0 ; // no-op S--; } signal (S) { S++; }

Lecture Outline. CS 5523 Operating Systems: Concurrency and Synchronization. a = 0; b = 0; // Initial state Thread 1. Objectives.

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

Threads. Jo, Heeseung

Reminder from last time

COSC 6374 Parallel Computation. Shared memory programming with POSIX Threads. Edgar Gabriel. Fall References

Synchronization I q Race condition, critical regions q Locks and concurrent data structures q Next time: Condition variables, semaphores and monitors

Threads. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Interprocess Communication and Synchronization

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

PRINCIPLES OF OPERATING SYSTEMS

In class we examined the need for concurrent execution paths like a consumer and a producer to synchronize their access to a shared ring buffer.

Deterministic Futexes Revisited

Concurrency and Synchronization. ECE 650 Systems Programming & Engineering Duke University, Spring 2018

Synchronization: Basics

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

20-EECE-4029 Operating Systems Spring, 2015 John Franco

CS345 Opera,ng Systems. Φροντιστήριο Άσκησης 2

Multi-threaded Programming

CSE 421/521 - Operating Systems Fall 2011 Recitations. Recitation - III Networking & Concurrent Programming Prof. Tevfik Kosar. Presented by...

Real Time Operating System Support for Concurrency

Parallel Programming with Threads

POSIX PTHREADS PROGRAMMING

TCSS 422: OPERATING SYSTEMS

C09: Process Synchronization

Process Synchronization

CS5460: Operating Systems

Synchronization: Basics

Concurrency: a crash course

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

Transcription:

Locks and semaphores Johan Montelius KTH 2017 1 / 41

recap, what s the problem : # include < pthread.h> volatile int count = 0; void * hello ( void * arg ) { for ( int i = 0; i < 10; i ++) { count ++; int main () { pthread_t p1, p2; pthread_create (& p1, NULL, hello, NULL ); pthread_create (&p2, NULL, hello, NULL ); 2 / 41

Peterson s algorithm int request [2] = {0,0; int turn = 0; int lock ( int id) { request [id] = 1; int other = 1-id; while ( request [ other ] == 1 && turn == other ) {; // spin return 1; void release ( int id) { request [id] = 0; 3 / 41

Total Store Order P1 P2 a b 0 0 a = 1 b = 1 read b read a 0 1 1 0 4 / 41

atomic memory operations All CPU:s provide several versions of atomic operations that both read and write to a memory element in one atomic operation. test-and-set: swap i.e. read and write to a memory location, the simplest primitive fetch-and-add/and/xor/... : update the value with a given operation, more flexible compare-and-swap : if the memory location contains a specific value then swap 5 / 41

try to lock by swap int try ( int * lock ) { sync_val_compare_and_swap (lock, 0, 1); pushq % rbp movq %rsp, % rbp movq %rdi, -8(% rbp ) movq -8(% rbp ), % rdx movl $0, % eax movl $1, % ecx lock cmpxchgl % ecx, (% rdx ) nop popq % rbp ret This is using GCC extensions to C, similar extensions available in all compilers. 6 / 41

a spin-lock int lock ( int * lock ) { while ( try ( lock )!= 0) { return 1; void release ( int * lock ) { * lock = 0; 7 / 41

finally - we re in control int global = 0; int count = 0; void * hello ( void * name ) { for ( int i = 0; i < 10; i ++) { lock (& global ); count ++; release (& global ); 8 / 41

spin locks 9 / 41

avoid spinning We need to talk to the operating system. void lock ( int * lock ) { while ( try ( lock )!= 0) { sched_yield (); // in Linux 10 / 41

Wham -... For how long should we sleep? We would like to be woken up as the lock is released - before you go-go. 11 / 41

a detour in Sun Solaris void lock ( lock_t *m) { while ( try (m-> guard )!= 0) {; void unlock ( lock_t *m) { while ( try (m-> guard )!= 0) { if(m-> flag == 0) { m-> flag = 1; m-> guard = 0; else { queue_add (m-> queue, gettid ()); m-> guard = 0; park (); if( empty (m-> queue )) { m-> flag = 0; else { unpark ( dequeue (m-> queue )) m-> guard = 0; 12 / 41

it s not easy It s not easy to to get it right. /* m-> flag == 1 */ : queue_add (m-> queue, gettid ()); m-> guard = 0; park (); // when I wake up the flag is set /* m-> flag == 1 */ : queue_add (m-> queue, gettid ()); setpark (); // if somone unparks now my park () is a noop m-> guard = 0; park (); if( empty (m-> queue )) { m-> flag = 0; else { // don t reset the flag unpark ( dequeue (m-> queue )); 13 / 41

back to Linux Introducing futex: fast user space mutex. futex_wait(mutex, val) : suspend on the mutex if its equal to val. futex_wake(mutex) : wake one of the treads suspended on the mutex In GCC you have to call them using a syscall() 14 / 41

a futex lock void lock ( volatile int * lock ) { while ( try ( lock )!= 0) { // time to sleep... futex_wait ( lock, 1); void unlock ( volatile int * lock ) * lock = 0; futex_wake ( lock ); Not very efficient - we want to avoid calling futex_wait() if no one is waiting. 15 / 41

pthread mutex Using Linux futex or Sun park/unpark directly is error prone and not very portable. It s better to use the pthread library API, probably more efficient and definitely less problems. Introducing pthread mutex locks: pthread_mutex_t : structure that is the mutex pthread_mutex_init(pthread_mutex_t *mutex,... pthread_mutex_destroy(pthread_mutex_t *mutex) pthread_mutex_lock(pthread_mutex_t *mutex) pthread_mutex_unlock(pthread_mutex_t *mutex) *attr) The lock procedure is platform specific, normally implemented as a combination of spinning and yield. 16 / 41

What could go wrong? Deadlock: the execution is stuck, no thread is making progress. Livelock: we re moving around in circles, all threads think that they are doing progress but we re stuck in a loop. Starvation: we re making progress but some threads are stuck waiting. Unfairness: we re making progress but some threads are given more of the resources. 17 / 41

Resources, priorities and scheduling Assume we have a fixed priority scheduler, three processes with high (H), medium (M) and low (L) priority and one critical resource. H: suspends on lock M: L: takes lock 0 10 20 30 40 50 60 70 80 90 100 110 120 18 / 41

Mars Pathfinder and Priority Inversion 19 / 41

Some examples concurrent counter a list a queue a hash table 20 / 41

the concurrent counter s t r u c t counter_t { i n t v a l ; void i n c r ( s t r u c t counter_t c ) { c >v a l ++; s t r u c t counter_t { i n t v a l ; pthread_mutex_t l o c k ; void i n c r ( s t r u c t counter_t c ) { p t h r e a d _ l o c k ( c >l o c k ) ; c >v a l ++; pthread_unlock ( c >l o c k ) ; 21 / 41

Do the right thing Doing the right thing often has a price. 22 / 41

sloppy counter 5 counter 0 local local local 2 2 thread 1 thread 2 thread 3 Sloppy vs Speed - do the right thing. 23 / 41

how about a list Simple solution: protect the list with one lock. Concurrent solution: allow several thread to operate on the list concurrently. concurrent reading: not a problem concurrent updating:... hmm, how would you solve it? Can we prove that we will never end up in a dead-lock? The concurrent solution might not be faster... but it s so much more challenging :-) 24 / 41

What about a queue Simple solution: protect the queue with one lock. Concurrent solution: allow threads to add elements to the queue at the same time as other remove elements. front end dummy 25 / 41

a hash table Simple solution: protect the table with one lock. Concurrent solution: allow threads to add elements to the table at the same time as other remove or search for elements. 26 / 41

an operating system Traditionally operating systems were single threaded - the obvious solution. The first systems that operated on multi-cpu architectures used one big kernel lock to avoid any problems with concurrency. An operating system that is targeting multi-core architectures will today be multi threaded and use fine grain locking to increase performance. How are things done in for example the JVM or Erlang? 27 / 41

beyond locks The locks that we have seen are all right: We can take a lock and prevent others from obtaining the lock. If someone holds the lock we will suspend execution. When the lock is released we will wake up and try to grab the lock again. We would like to suspend and only be woken up if a specified condition holds true. 28 / 41

the queue revisited front end dummy What do we do now? 29 / 41

conditional variables Introducing pthread conditional variables: pthread_cond_t : the data structure of a conditional variable pthread_cond_init(pthread_cond_t *restrict cond,...) pthread_cond_destroy(pthread_cond_t *cond) pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) pthread_cond_signal(pthread_cond_t *cond) pthread_cond_broadcast(pthread_cond_t *cond) The exact declarations are slightly more complicated, check the man pages. 30 / 41

the producer/consumer A single element buffer, multiple consumers, multiple producers. int buffer ; int count = 0; void put ( int value ) { assert ( count == 0); count = 1; buffer = value ; int get () { assert ( count == 1); count = 0; return buffer ; Let s try to make this work. 31 / 41

this will not work void produce ( int val ) { put ( val ); int consume () { int val = get (); return val ; 32 / 41

add a mutex and cond variable pthread_cond_t cond ; pthread_mutex_t mutex ; produce ( i n t v a l ) { pthread_mutex_lock (&mutex ) ; i f ( count == 1) pthread_cond_wait(&cond, &mutex ) ; put ( i ) ; p t h r e a d _ c o n d _ s i g n a l (&cond ) ; pthread_mutex_unlock(&mutex ) ; When does this work, when does it not work? i n t consume ( ) { pthread_mutex_lock(&mutex ) ; i f ( count == 0) pthread_cond_wait(&cond, &mutex ) ; i n t v a l = get ( ) ; p t h r e a d _ c o n d _ s i g n a l (&cond ) ; pthread_mutex_unlock(&mutex ) ; return v a l ; 33 / 41

a race condition If you re signaled to wake up - it might take some time before you do wake up. 34 / 41

better pthread_cond_t filled, empty ; pthread_mutex_t mutex ; produce ( i n t v a l ) { i n t consume ( ) { pthread_mutex_lock (&mutex ) ; while ( count == 1) pthread_cond_wait(&empty, &mutex ) ; : p t h r e a d _ c o n d _ s i g n a l (& f i l l e d ) ; : pthread_mutex_lock(&mutex ) ; while ( count == 0) pthread_cond_wait(& f i l l e d, &mutex ) : p t h r e a d _ c o n d _ s i g n a l (&empty ) ; : 35 / 41

a larger buffer int buffer [ MAX ]; int * getp = 0; in * putp = 0; int count = 0; void put ( int value ) { assert ( count < MAX ); buffer [ putp ] = value ; putp = putp + 1 % MAX ; count ++; int get () { assert ( count > 0); int val = buffer [ getp ]; getp = getp + 1 % MAX count -- return val ; 36 / 41

final touch produce ( int val ) { : while ( count == MAX ) pthr ead_c ond_wa it (& empty, & mutex ); : int consume () { : while ( count == 0) pthr ead_c ond_wa it (& filled, & mutex ); : Can we allow a producer to add an entry while another removes an entry? 37 / 41

Where are we now? atomic test and set: we need it spin locks: simple to use but have some problems wait and wake : avoid spinning condition variables : don t wake up if it s not time to continue Is there more? 38 / 41

Semaphores Properties of a semaphore: holds a number only allow threads to pass is number is above 0 passing threads decremented the number a thread can increment the number A semaphore is a counter of resources. 39 / 41

POSIX semaphores #include <semaphore.h> sem_t : the semaphore data structure sem_init(sem_t *sem, int pshared, unsigned int value): could be shared between processes int sem_destroy(sem_t *sem) sem_wait(sem_t *sem) sem_post(sem_t *sem) 40 / 41

Summary 41 / 41