+ All Categories
Home > Documents > CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman [email protected].

CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman [email protected].

Date post: 19-Dec-2015
Category:
View: 217 times
Download: 0 times
Share this document with a friend
Popular Tags:
24
CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman [email protected]
Transcript
Page 1: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

CS444/CS544Operating Systems

Synchronization

2/16/2007

Prof. Searleman

[email protected]

Page 2: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

CS444/CS544 Spring 2007 Synchronization Primitives

HW primitives: enable/disable interrupts Atomic test-and-set

Software primitives: locks, semaphores Implementing software primitives using HW

Spinlocks & busy waiting Implementations that block the waiting process/thread

Reading assignment: Chapter 6

Page 3: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Recap: Peterson’s Solution

T0

repeat enter_critical(0); c.s. exit_critical(0);forever;

T1

repeat enter_critical(1); c.s. exit_critical(1);forever;

turn

initially 0

0

interested

initially both FALSE

FALSE FALSE

0 1

void enter_critical(int me) { int you; you = 1 – me; interested[me] = TRUE; turn = you; while (interested[you] && turn == you) ;}

void exit_critical(int me) { interested[me] = FALSE;}

Page 4: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Synchronization Primitives

Synchronization Primitives are used to implement a solution to the critical section problem

OS uses HW primitives Disable Interrupts HW Test and set

OS exports primitives to user applications; User level can build more complex primitives from simpler OS primitives Locks Semaphores Monitors Messages

Page 5: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Locks

Object with two simple operations: lock and unlock

Threads use pairs of lock/unlock Lock before entering a critical section Unlock upon exiting a critical section If another thread in their critical section, then lock

will not return until the lock can be acquired Between lock and unlock, a thread “holds” the

lock

Page 6: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

7.6 Silberschatz, Galvin and Gagne ©2005Operating System Concepts

6.216.21

Page 7: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Withdraw revisitedint withdraw (int account, int amount) { lock(whichLock(account));

balance = readBalance(account); balance = balance - amount; updateBalance(account, balance);

unlock(whichLock(account));

return balance;}

ENTER CRITICAL SECTION

CRITICAL SECTION

EXIT CRITICAL SECTION

What would happen if the programmer forgot lock? No exclusive accessForgot unlock? deadlockput it at the wrong place? called lock or unlock in both places?

Consider the locking granularity? One lock or one lock per account?Is it ok for return to be outside the critical section?

Page 8: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

$500 - $100 - $100 = $300

Before you get too happy, deposits can be lost just as easily!

lock (whichLock(account));balance = readBalance(account);

balance = balance - amount; updateBalance(account, balance);unlock (whichLock(account));

lock (whichLock(account));

balance = readBalance(account);balance = balance - amount; updateBalance(account, balance);unlock (whichLock(account));

BLOCKS!

UNTIL GREEN UNLOCKS

Page 9: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Implementing Locks

Ok so now we have seen that all is well *if* we have these objects called locks

How do we implement locks? Recall: The implementation of lock has a critical

section too (read lock; if lock free, write lock taken) Need help from hardware

Make basic lock primitive atomic Atomic instructions like test-and-set or read-modify –

write, compare-and-swap Prevent context switches

Disable/enable interrupts

Page 10: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Disable/enable interrupts

Recall how the OS can implement lock as disable interrupts and unlock as enable interrupts

Problems Insufficient on a multiprocessor because only

disable interrupts on the single processor Cannot be used safely at user-level -not even

exposed to user-level through some system call! Once interrupts are disabled, there is no way for the

OS to regain control until the user level process/thread yields voluntarily (or requests some OS service)

Page 11: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Test-and-set Suppose the CPU provides an atomic test-and-

set instruction with semantics much like this:bool test_and_set( bool *flag ){

bool old = *flag; *flag = true; return old; //did you capture the “false” ie not

//previously set?}

Without an instruction like this, use multiple instructions (not atomic)load $register $mem vs. test-and-set $register $mem

store 1 $mem

Page 12: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Implementing a lock with test-and-set

struct lock_t {

bool held = FALSE;

}

void lock( lock_t *l){

while (test_and_set(lock->held)){};

}

void unlock( lock_t *l){

lock->held = FALSE;

}

When call lock function, if the lock is not held (by someone else ) thenwill swap FALSE for TRUE atomically!!! Test_and_setwill return FALSE jumpingout of the while loop withthe lock held

When call lock function,if the lock is held (by someone else) then willfrantically swap TRUE for TRUE many times until other person calls unlock

Notice: Locks build from test and set aresafe for user level applications – unlikeDisable/enable interrupts!

Page 13: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Spinlocks

The type of lock we saw on the last slide is called a spinlock If try to lock and find already locked then will spin waiting

for the lock to be released

Very wasteful of CPU time! Thread spinning still uses its full share of the CPU cycles

waiting – called busy waiting During that time, thread holding the lock cannot make

progress! What if thread waiting has higher priority than the threads

holding the lock!!

So safe even at user-level but inefficient

Page 14: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Avoiding Busy Waiting

Could modify the lock call to the followingvoid lock( lock_t *l){

while (test_and_set(lock->held)){

yield the CPU

};

}

But still pay for context switch overhead each time

Page 15: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Other choices? OS can build a lock with the following properties

When lock is called if the process or thread does not acquire the lock, it is taken off the ready queue and put on a special queue of processes that are waiting for the lock to be released

When a lock is released, the OS could choose a waiting process to grant the lock to and place it back on the ready queue

You can think of this as a lock that just happens to be implemented with a queue inside, but this is often called a semaphore

Page 16: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Semaphores

Recall: the lock object has one data member the boolean value, held

The semaphore object has two data members: an integer value and a queue of waiting processes/threads

Page 17: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Wait and Signal Recall: Locks are manipulated through two

operations: lock and unlock Semaphores are manipulated through two

operations: wait and signal Wait operation (like lock)

Decrements the semaphore’s integer value and blocks the thread calling wait until the semaphore is available

Also called P() after the Dutch word, proberen, to test Signal operation (like unlock)

Increments the semaphore’s integer value and if threads are blocked waiting, allow one to “enter” the semphore

Also called V() after the Dutch word, verhogen, to increment Why Dutch? Semaphores invented by Edgar Dijkstra

for the THE OS (strict layers) in 1968

Page 18: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Withdraw revisited

int withdraw (int account, int amount) { wait(whichSemaphore(account));

balance = readBalance(account); balance = balance - amount; updateBalance(account, balance);

signal(whichSemaphore(account));

return balance;}

ENTER CRITICAL SECTION

CRITICAL SECTION

EXIT CRITICAL SECTION

Initialize value of semaphore to 1 Functionally like a lock

Page 19: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Implementing a semaphorestruct semaphore_t {

int value; queue waitingQueue;}void wait( semaphore_t *s){

s->value--; if (s->value < 0){

add self to s->waitingQueue block}

}void signal( semaphore_t *s){

s->value++;if (s->value <=0) {

P =remove process from s->waitingQueue

wakeup (P)}

Whats wrong with this?

Page 20: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Implementing a semaphore with a lock

struct semaphore_t {

int value;

queue waitingQueue;

lock_t l;

}void wait( semaphore_t *s){ lock(&s->l);

s->value--; if (s->value < 0){

add self to s->waitingQueue unlock(&s->l); block} else {

unlock(&s->l);}

}

void signal( semaphore_t *s){lock(&s->l);s->value++;if (s->value <=0) {

P = remove process from

s->waitingQueueunlock(&s->l);wakeup (P)

} else {unlock(&s-l);

}}

Page 21: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Semaphore’s value

When value > 0, semaphore is “open” Thread calling wait will continue (after

decrementing value) When value <= 0, semaphore is “closed”

Thread calling wait will decrement value and block

When value is negative, it tells how many threads are waiting on the semaphore

What would a positive value say?

Page 22: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Binary vs Counting Semaphores

Binary semaphore Semaphore’s value initialized to 1 Used to guarantee exclusive access to shared

resource (functionally like a lock but without the busy waiting)

Counting semaphore Semaphore’s value initialized to N >0 Used to control access to a resource with N

interchangeable units available (Ex. N processors, N pianos, N copies of a book,…)

Allow threads to enter semaphore as long as sufficient resources are available

Page 23: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Semaphore’s Waiting Queue

Recall: good to integrate semaphore’s waiting queue with scheduler When placed on waitingQueue should be removed from

runningQueue Could use scheduling priority to decide who on queue

enters semaphore when it is open next Beware of starvation just like in priority scheduling

If OS exports semaphore, then kernel scheduler aware of waitingQueue

If user-level thread package exports semaphore, then user-level thread scheduler (scheduling time on the available kernel threads) aware of waitingQueue

Page 24: CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman jets@clarkson.edu.

Is busy-waiting eliminated?

Threads block on the queue associated with the semaphore instead of busy waiting

Busy waiting is not gone completely When accessing the semaphore’s critical section, thread holds

the semaphore’s lock and another process that tries to call wait or signal at the same time will busy wait

Semaphore’s critical section is normally much smaller than the critical section it is protecting so busy waiting is greatly minimized

Also avoid context switch overhead when just checking to see if can enter critical section and know all threads that are blocked on this object


Recommended