Concurrency Operating Systems Spring 2004 OS Spring’04
Concurrency pros and cons • Concurrency is good for users • One of the reasons for multiprogramming • Working on the same problem, simultaneous execution of programs, background execution • Concurrency is a “pain in the neck” for the system • Access to shared data structures • Deadlock due to resource contention OS Spring’04
Mutual Exclusion • OS is an instance of concurrent programming • Multiple activities may take place in the same time • Concurrent execution of operations involving multiple steps is problematic • Example: updating linked list • Concurrent access to a shared data structure must be mutually exclusive OS Spring’04
new->next=current.next insert_after(current,new): current.next=new new current new current OS Spring’04
remove_next(current): tmp=current.next; current.next=current.next.next; free(tmp); current current OS Spring’04
new current new current new current OS Spring’04
Atomic operations • A generic solution is to ensure atomic execution of operations • All the steps are perceived as executed in a single point of time insert_after(current,new) remove_next(current), or remove_next(current) insert_after(current,new) OS Spring’04
A code within a critical section must be executed exclusively by a single process entry section exit section The Critical Section Model do { critical section remainder section } while(1) OS Spring’04
entry section exit section entry section exit section Linked list example do { do { tmp=current.next; current.next=current.next.next; free(tmp); new->next=current.next current.next=new remainder section remainder section } while(1) } while(1) OS Spring’04
The Critical Section Problem • n processes P0,…,Pn-1 • No assumptions on relative process speeds, no synchronized clocks, etc… • Models inherent non-determinism of process scheduling • No assumptions on process activity when executing within • Critical and reminder sections OS Spring’04
Shared variables • Processes are communicating through shared atomic read/write variables • x is a shared variable, l is a local variable • Read: takes the current value: • Write: assigns a provided value: OS Spring’04
Requirements • Mutual Exclusion: If process Pi is executing its C.S., then no other process is in its C.S. • Progress: If Pi is in its entry section and no process is in C.S., then some process eventually enters C.S. • Fairness: If no process remains in C.S. forever, then each process requesting entry to C.S. will be eventually let into C.S. OS Spring’04
Solving the CS problem (n=2) OS Spring’04
Solving the CS problem (n=2) OS Spring’04
Solving the CS problem (n=2) OS Spring’04
Peterson’s algorithm for n=2 OS Spring’04
Bakery algorithm of Lamport • Critical section algorithm for any n>1 • Each time a process is requesting an entry to CS, assign it a ticket which is • Unique and monotonically increasing • Let the process into CS in the order of their numbers OS Spring’04
Does not guarantee uniqueness! Use process Ids: Process need to know that somebody perhaps chose a smaller number: Choosing a ticket OS Spring’04
Bakery algorithm for n processes OS Spring’04
Correctness Lemma: Mutual exclusion is immediate from this lemma It is easy to show that Progress and Fairness hold as well (recitation) OS Spring’04
Hardware primitives • Elementary building blocks capable of performing certain steps atomically • Should be universal to allow for solving versatile synchronization problems • Numerous such primitives were identified: • Test-and-set • Fetch-and-add • Compare-and-swap OS Spring’04
boolean test-and-set(boolean &lock) { temp=lock; lock=TRUE; return temp; } reset(boolean &lock) { lock=FALSE; } Test-and-Set (TS) OS Spring’04
Critical section using TS Shared boolean lock, initially FALSE do { while(test-and-set(&lock)); critical section; reset(&lock); reminder section; } while(1); • Check yourself! • Is mutual exclusion satisfied? • Is progress satisfied? • Is fairness satisfied? OS Spring’04
Discussion • Satisfies Mutual Exclusion and Progress • Does not satisfy Fairness • Provides exclusion among unbounded number of processes • Process IDs and number are unknown • Busy waiting • Burning CPU cycles while being blocked OS Spring’04
Fetch-and-Add (FAA) s: shared, a: local int FAA(int &s, int a) { temp=s; s=s+a; return temp; } FAA can be used as a ticket machine OS Spring’04
Critical section using FAA Shared: int s, turn; Initially: s = 0; turn=0; Process Pi code: Entry: me = FAA(s,1); while(turn < me); // busy wait for my turn Critical section Exit: FAA(turn,1); • Check yourself! • Is mutual exclusion satisfied? • Is progress satisfied? • Is fairness satisfied? OS Spring’04
Discussion • Satisfies all three properties • Supports unbounded number of processes • Unbounded counter • Busy waiting OS Spring’04
Problems with studied synchronization methods • Critical section framework is inconvenient for programming • Performance penalty • Busy waiting • Too coarse synchronization • Using hardware primitives directly results in non-portable code OS Spring’04
Higher Level Abstractions • Higher level software abstractions are represented by • Semaphores • Monitors OS Spring’04
Semaphores • Invented by Edsger Dijkstra in 1968 • Interface consists of two primitives: • P() and V() OS Spring’04
Notes on the Language • Dutch: P: Proberen, V: Verhogen • Hebrew: P: פחות, V: ועוד • English: P(): wait(), V(): signal() OS Spring’04
Semaphores: initial value • Initial value of a semaphore indicates how many identical instances of the critical resource exist • A semaphore initialized to 1 is called a mutex (mutual exclusion) OS Spring’04
Programming with semaphores • Semaphores is a powerful programming abstraction • Define a semaphore for each critical resource • E.g., one for each linked list • Granularity? • Concurrent processes access appropriate semaphores when synchronization is needed OS Spring’04
Some examples … P(synch); … … … … … … … … … V(synch); … … OS Spring’04
Some examples Do { P(mutex); critical section V(mutex); Remainder section; While(1); OS Spring’04
Implementing semaphores • Semaphores can be implemented efficiently by the system • P() is explicitly telling the system: “Hey, I cannot proceed, you can preempt me” • V() instructs the system to wake up a waiting process OS Spring’04
Implementing Semaphores type semaphore = record count: integer; queue: list of process end; var S: semaphore; S.count must be initialized to a nonnegative value (depending on application) OS Spring’04
Implementing Semaphores P(S): S.count--; if (S.count<0) { add this process to S.queue block this process; } V(S): S.count++; if (S.count <= 0) { remove a process P from S.queue place this process P on ready queue } OS Spring’04
We’re still cheating… • P() and V() must be executed atomically • In uniprocessor system may disable interrupts • In multi-processor system, use hardware synchronization primitives • TS, FAA, etc… • Involves a some limited amount of busy waiting OS Spring’04
Only a single process at a time can be active within the monitor => other processes calling Pi() are queued Conditional variables for finer grain synchronization x.wait() suspend the execution until another process calls x.signal() Monitors monitor monitor-name { shared variable declarations procedure P1(…) { … } … procedure Pn() { … } } OS Spring’04