Lecture 10: Synchronization (Cont) + MCS locks Operating System Concepts – 8th Edition, Silberschatz, Galvin and Gagne ©2009 TestAndSet Instruction boolean TestAndSet (boolean *target) { boolean rv = *target; *target = TRUE; return rv: } Operating System Concepts – 8th Edition 6.2 Silberschatz, Galvin and Gagne ©2009 Swap Instruction void Swap (boolean *a, boolean *b) { boolean temp = *a; *a = *b; *b = temp: } Operating System Concepts – 8th Edition 6.3 Silberschatz, Galvin and Gagne ©2009 Solution using Swap Shared Boolean variable lock initialized to FALSE; Each process has a local Boolean variable key Solution: do { key = TRUE; while ( key == TRUE) Swap (&lock, &key); // critical section lock = FALSE; // remainder section } while (TRUE); Operating System Concepts – 8th Edition 6.4 Silberschatz, Galvin and Gagne ©2009 Bounded-waiting Mutual Exclusion with TestAndSet() do { waiting[i] = TRUE; key = TRUE; while (waiting[i] && key) key = TestAndSet(&lock); waiting[i] = FALSE; // critical section j = (i + 1) % n; while ((j != i) && !waiting[j]) j = (j + 1) % n; if (j == i) lock = FALSE; else waiting[j] = FALSE; // remainder section } while (TRUE); Operating System Concepts – 8th Edition 6.5 Silberschatz, Galvin and Gagne ©2009 Caches and Consistency in Multiprocessors memory cache ICN cache cache ..... cache with each processor to hide latency for memory accesses miss in cache => go to memory to fetch data multiple copies of same address in caches caches need to be kept consistent Operating System Concepts – 8th Edition 6.6 Silberschatz, Galvin and Gagne ©2009 Cache Coherence write-invalidate invalidate --> X -> X’ memory ICN X -> Inv X -> Inv ..... Before a write, an “invalidate” command goes out on the bus. All other processors are “snooping” and they invalidate their caches. Invalid entries cause read faults and new values will be fetched from main memory. Operating System Concepts – 8th Edition 6.7 Silberschatz, Galvin and Gagne ©2009 Cache Coherence As soon as the cache line is written, it is broadcast on the bus, so all processors update their caches. write-update (also called distributed write) memory update --> X -> X’ ICN X -> X’ X -> X’ ..... Operating System Concepts – 8th Edition 6.8 Silberschatz, Galvin and Gagne ©2009 Blocking vs. Busy-Waiting Busy-waiting is preferable when: scheduling overhead is larger than expected wait time processor resources are not needed for other tasks schedule-based blocking is inappropriate (e.g., in OS kernel) But typically it produces lots of network traffic hot-spots Operating System Concepts – 8th Edition 6.9 Silberschatz, Galvin and Gagne ©2009 Test-and-Set Locking do { Lock is free: value is false Lock is taken: value is true while ( TestAndSet (&lock )) ; // do nothing Acquire lock by calling TAS If result is false, you win If result is true, you lose // critical section Release lock by writing false Done using a RMW HW-supported op lock = FALSE; Invalidates cache lines Spinners: // Miss in cache, hence go to buss (contention) remainder section } while (TRUE); Thread wants to release lock delayed behind spinners Operating System Concepts – 8th Edition 6.10 Silberschatz, Galvin and Gagne ©2009 Test-and-Test-and-Set Delay the “set” (write op) for when likely to get the lock If the previous read suggests test-and-set may succeed This reduces cache invalidations Bus contention still a problem when lock released Operating System Concepts – 8th Edition 6.11 Silberschatz, Galvin and Gagne ©2009 Backoff Lock Delay consecutive probing on the lock If the lock looks free but I fail to get it, there must be lots of contention. Better to back off than to collide again Constant Operating System Concepts – 8th Edition delay, exponential backoff, etc. 6.12 Silberschatz, Galvin and Gagne ©2009 The Ticket Lock Reduces the number of attempts to update the lock to minimum: update the lock only when able to take it Probes with read ops only (thus, not cache invalidations) Lock = (requests, releases) Request lock: my_ticket = fetch_and_increment(requests) Acquire lock: when my_ticket==releases Release lock: increment(releases) One write per lock request, many reads Can be reduced by (proportional) backoff Operating System Concepts – 8th Edition 6.13 Silberschatz, Galvin and Gagne ©2009 Array-Based Queuing Locks Threads in a queue Acquire the lock in FIFO order A thread acquires the lock when its predecessor in the queue finished with it. Operating System Concepts – 8th Edition 6.14 Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock Slides from The Art of Multiprocessor Programming, by Herlihy-Shavit, 2007 idle next flags T F Operating System Concepts – 8th Edition F F F 6.15 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquiring next getAndIncrement flags T F Operating System Concepts – 8th Edition F F F 6.16 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquiring next getAndIncrement flags T F Operating System Concepts – 8th Edition F F F 6.17 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquired next Mine! flags T F Operating System Concepts – 8th Edition F F F 6.18 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquiring acquired next flags T F Operating System Concepts – 8th Edition F F F 6.19 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock next getAndIncrement flags T acquiring acquired F Operating System Concepts – 8th Edition F F F 6.20 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock next getAndIncrement flags T acquiring acquired F Operating System Concepts – 8th Edition F F F 6.21 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquiring acquired next flags T F Operating System Concepts – 8th Edition F F F 6.22 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquired released next flags T T Operating System Concepts – 8th Edition F F F 6.23 F F F Silberschatz, Galvin and Gagne ©2009 Anderson Queue Lock acquired released next Yow! flags T T Operating System Concepts – 8th Edition F F F 6.24 F F F Silberschatz, Galvin and Gagne ©2009 MCS (Mellor-Crummey-Scott) Guarantees FIFO ordering on lock acquisition Spins on locally-accessible flag variables only Requires a small constant amount of space per lock Works well on machines with or without cache coherence Operating System Concepts – 8th Edition 6.25 Silberschatz, Galvin and Gagne ©2009 QuickTime™ and a decompressor are needed to see this picture. Operating System Concepts – 8th Edition 6.26 Silberschatz, Galvin and Gagne ©2009 Semaphores (by Dijkstra 1930 – 2002) Born in Rotterdam, The Netherlands 1972 recipient of the ACM Turing Award Responsible for The idea of building operating systems as explicitly synchronized sequential processes The formal development of computer programs Best known for His efficient shortest path algorithm Having designed and coded the first Algol 60 compiler. Famous campaign for the abolition of the GOTO statement Also known for his hand-written communications with friends and colleagues. For example: http://www.cs.utexas.edu/users/EWD/ewd12xx/EWD1205.PDF Operating System Concepts – 8th Edition 6.27 Silberschatz, Galvin and Gagne ©2009 Semaphore Synchronization tool that does not require busy waiting Semaphore S – integer variable Two standard operations modify S: wait() and signal() Originally called P() and V() Less complicated Can only be accessed via two indivisible (atomic) operations wait (S) { while S <= 0 ; // no-op S--; } signal (S) { S++; } Operating System Concepts – 8th Edition 6.28 Silberschatz, Galvin and Gagne ©2009 Semaphore as General Synchronization Tool Counting semaphore – integer value can range over an unrestricted domain Binary semaphore – integer value can range only between 0 and 1; can be simpler to implement Also known as mutex locks Can implement a counting semaphore S as a binary semaphore Provides mutual exclusion Semaphore mutex; // initialized to 1 do { wait (mutex); // Critical Section signal (mutex); // remainder section } while (TRUE); Operating System Concepts – 8th Edition 6.29 Silberschatz, Galvin and Gagne ©2009 Semaphore Implementation Must guarantee that no two processes can execute wait () and signal () on the same semaphore at the same time Thus, implementation becomes the critical section problem where the wait and signal code are placed in the crtical section. Could now have busy waiting in critical section implementation But implementation code is short Little busy waiting if critical section rarely occupied Note that applications may spend lots of time in critical sections and therefore this is not a good solution. Operating System Concepts – 8th Edition 6.30 Silberschatz, Galvin and Gagne ©2009 Semaphore Implementation with no Busy waiting With each semaphore there is an associated waiting queue. Each entry in a waiting queue has two data items: value (of type integer) pointer to next record in the list Two operations: block – place the process invoking the operation on the appropriate waiting queue. wakeup – remove one of processes in the waiting queue and place it in the ready queue. Operating System Concepts – 8th Edition 6.31 Silberschatz, Galvin and Gagne ©2009 Semaphore Implementation with no Busy waiting (Cont.) Implementation of wait: wait(semaphore *S) { S->value--; if (S->value < 0) { add this process to S->list; block(); } } Implementation of signal: signal(semaphore *S) { S->value++; if (S->value <= 0) { remove a process P from S->list; wakeup(P); } } Operating System Concepts – 8th Edition 6.32 Silberschatz, Galvin and Gagne ©2009 Deadlock and Starvation Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes Let S and Q be two semaphores initialized to 1 P0 P1 wait (S); wait (Q); wait (Q); wait (S); . . . . . . signal (S); signal (Q); signal (Q); signal (S); Starvation – indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended Priority Inversion - Scheduling problem when lower-priority process holds a lock needed by higher-priority process Operating System Concepts – 8th Edition 6.33 Silberschatz, Galvin and Gagne ©2009