Concurrency Lecture
Concurrency Lecture
Mageda Sharafeddin
mageda.sharafeddin@pu.edu.lb
Outline
Overview
Concurrency issues
Producer consumer problem
Producer/Consumer
Critical regions
Mutual exclusion
Peterson
Atomic operations
Dining philosophers
Condition variables
Monitor construct
Transactional memory
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Concurrency
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Race Conditions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Concurrency issues
▶ Deadlocks
▶ Process P0 has resource A and waits for B
▶ Process P1 has resource B and waits for A
▶ Livelocks
▶ Adnan meets Ammar in a narrow corridor
▶ Adnan and Ammar both politely back up
▶ Both move forward thinking the other opened the way
▶ May occur when we try to avoid a deadlock
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Lock Variables
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Producer-consumer – 1
Race condition
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Producer-consumer
Summary of Algorithm
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Producer-consumer
Sleep/wakeup problem
Producer-consumer
Solution!!
Critical regions
Mutual exclusion
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
▶ Hassan ▶ Zeinab
▶ Checks for bread ▶ -
▶ Goes to market ▶ -
▶ Buys bread ▶ Checks for bread
▶ Happy fridge ▶ Goes to marker
▶ Buys bread
▶ Lots of bread
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Peterson’s algorithm
Take a turn and leave a note
Process 0 Process 1
flag[0] = 1; flag[1] = 1;
turn = 1;//Hassan turn = 0;//Zeinab
while( flag[1] && while( flag[0] &&
turn == 1 ); turn == 0 );
criticalBuyBread(); criticalBuyBread();
flag[0] = 0; flag[1] = 0;
nonCritical(); nonCritical();
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
▶ The process that enters the critical region is the one that:
▶ Calls the enter_region with its own process number.
▶ This might cause it to wait if needed.
▶ After finishing with the shared variable, it calls the
leaves_region to allow the other process to enter.
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Peterson’s algorithm
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
What is wrong?
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Critical regions
Execution
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
TSL Instruction
Help from hardware: TSL
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
TSL Instruction
How it works
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Critical regions
Implementation with the Test and set lock (TSL) instruction
enter_region:
TSL REGISTER,LOCK | copy lock to register and set lock to 1
CMP REGISTER,#0 | was lock zero?
JNE enter_region | if it was not zero, lock was set, so loop
RET |return to caller; critical region entered
leave_region:
MOVE LOCK,#0 | store a 0 in lock
RET |return to caller
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Critical regions
Implementation with the XCHG instruction
enter_region:
MOVE REGISTER,#1 | put a 1 in the register
XCHG REGISTER,LOCK | swap the contents of the register and lock variable
CMP REGISTER,#0 | was lock zero?
JNE enter_region | if it was non zero, lock was set, so loop
RET | return to caller; critical region entered
leave_region:
MOVE LOCK,#0 | store a 0 in lock
RET | return to caller
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Atomic operations
Definition
Either all effects of an atomic operation happen, or none happen.
Definition
An atomic operation is an isolated operation that is not affected by
concurrent operations.
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Semaphores
An invention by Dijkstra
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Semaphores
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
More on Semaphore
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
▶ The processes spin using CPU cycles while waiting for the
lock
▶ Busy waiting is also known as spinlock
▶ With a semaphore the process can block itself
▶ Waits in a semaphore queue to be called when the semaphore
is available
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Explanation of Producer-Consumer
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Producer-consumer ??
Philosopher
semaphore chopstick[5]=
{1,1,1,1,1}; // pseudo
do {
down(chopstick[i]);
down(chopstick([i+1) % 5]);
eat();
up(chopstick[i]);
up(chopstick[(i+1) % 5]);
think();
} while(true);
▶ Do you anticipate any problems?
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Mutexes in use
Implementation with the Test and set lock (TSL) instruction
mutex_lock:
TSL REGISTER,MUTEX | copy mutex to register and set mutex to 1
CMP REGISTER,#0 | was mutex zero?
JZE ok | if it was zero, mutex was unlocked, so return
CALL thread_yield | mutex is busy; schedule another thread
JMP mutex_lock | try again
ok: RET | return to caller; critical region entered
mutex_unlock:
MOVE MUTEX,#0 | store a 0 in mutex
RET
More on Mutexes
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Condition variables
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Producer Consumer
Lock lock;
Condition notFull, notEmpty;
produce() { consume() {
lock.acquire(); lock.acquire();
while(count==N) while(count==0)
notFull.wait(&lock); notEmpty.wait(&lock);
ProduceItem(); ConsumeItem();
count++; count--;
notEmpty.signal(); notFull.signal();
lock.release(); } lock.release();}
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Condition variables
Comparison to semaphores
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
monitor diningPhilosophers {
enum{think, hungry, eat} ▶ Only one executing function per
state[5] = think[5];
condition me[5]; monitor code
void test(i) { ▶ Wait for neighbors to eat
if (neighbors(i) != eat &&
state[i] == hungry) {
state[i] = eat;
▶ condition can wait and signal
me[i].signal(); ▶ signal different than up as it
} }
void vEat(int i) { does not change the state
state[i] = hungry;
test(i);
if (state[i] != eat)
▶ Problem: starvation
me[i].wait();
}
void vThink(int i) {
state[i] = think;
test(left(i));
test(right(i));
}
}
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Monitors
▶ Hansen semantics
▶ Hoare semantics 1. Thread T1 waits on C
1. Thread T1 waits on C 2. Thread T2 in the monitor
2. Thread T2 in the monitor 3. T2 calls C.signal() and
3. T2 calls C.signal() wakes up T1
4. T2 gives up monitor and 4. T2 continues and finishes
blocks 5. T1 wakes up, takes over
5. T1 takes monitor, runs monitor
6. T1 gives up monitor 6. T1 runs, completes
7. T2 takes monitor, resumes
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
▶ Hansen semantics
▶ Hoare semantics ▶ Used in systems
▶ Textbookish, easily ▶ Signal is a hint that
provable condition may be true
▶ Clean ▶ Need to check condition
▶ Implementation is not before resuming
efficient ▶ May introduce buggy
▶ Not easy to get correctness synchronization
▶ Implementation is efficient
▶ Final note on condition variables within monitors: unlike sleep
and wakeup where wakeup could fail because while one
process was trying to go to sleep, the other one was trying to
wake it up. With monitors, that cannot happen.
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Summary
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Transactional memory
Critical regions: atomicity and isolation
▶ Isolation
▶ Buffer changes to memory
▶ Hide buffers from other processes
▶ Atomicity
▶ On error, reset buffers to value in real memory
▶ On success, commit changes to real memory
▶ We need hardware or OS support for buffering and
committing values
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
produce() { consume() {
atomic { atomic {
if (count == n) { if (count == 0) {
retry; } retry; }
produceItem(); consumeItem();
count++; count--;
} } } }
▶ {RP , WP , RC , WC } Divide address space into Read and
Write categories per transaction
▶ Safe when WP ∩ (RC ∪ WC ) is empty
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Disabling interrupts
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
▶ All CPUs
▶ Atomic operations, spin-locks, semaphore, global interrupt
disable
▶ Local CPU
▶ Memory barrier, local interrupt disable, local softIRQ disable
▶ Atomic instructions are
▶ Instructions with no or only 1 aligned memory access (last 2
bits are 0 on a 32-bit address)
▶ Lock prefixed instructions with read, modify, and write access
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Problem Hint
//guarantee that a1 happens before b2 semaphore aArrived(0);
// and b1 happens before a2 semaphore bArrived(0);
Thread A
statement a1
statement a2
Thread B
statement b1
statement b2
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Rendezvous solution
Thread A
statement a1
aArrived.up();
bArrived.down();
statement a2
Thread B
statement b1
bArrived.up();
aArrived.down();
statement b2
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Thread
rendezvous
critical section
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Barrier solution
AKA turnstile
Hint
Thread // N is the number of threads
rendezvous int count = 0;
mutex.down(); semaphore mutex(1);
count++; semaphore barrier(0);
if (count == n) barrier.up();
mutex.up();
barrier.down(); // is it ok to read count?
barrier.up();
critical section
mutex.down();
count--; // how many times do we signal?
if (count == 0) barrier.down();
// What if we want to reuse the
mutex.up();
// barrier?
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Leader Hint
wait for follower
dance(); leaderQ wait/signal;
followerQ wait/signal;
Follower
wait for leader
dance();
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Leader Follower
followerQ.signal(); leaderQ.signal();
leaderQ.wait(); followerQ.wait();
dance(); dance();
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
OS Phoenicia University
Concurrency P/C Regions Philosophers Transactions
Writer Reader
semaphore mutex = 1; void reader(void)
semaphore db = 1; {
int rc = 0; while (TRUE) {
void writer(void) down(&mutex);/*protect rc*/
{ rc = rc+1;
while (TRUE) { if (rc == 1) /*first reader*/
no_critical_region( ); down(&db);
down(&db); up(&mutex);
write_database( ); read_database();
up(&db); down(&mutex);
} rc = rc-1;
} if (rc == 0) /*last reader*/
up(&db);/*all done,release*/
up(&mutex);
non_critical_region();
}
}
OS Phoenicia University