Basic Synchronization Semaphores © 2004, D. J. Foreman
One Problem (of many) What if an interrupt occurs and t2 gets control? T1 T2 count++ //compiles as: count-- //compiles as: register1 = count register2 = count register1 = register1 + 1 register2 = register2 - 1 count = register1 count = register2 What if an interrupt occurs and t2 gets control? This is a “Critical Section” Incorrect values of "count" can result due to time-slicing How do we prevent such errors Note: "count" is global © 2004, D. J. Foreman
Conditions/Requirements n threads competing for shared data Each thread has a code segment, called a critical section, (CS) which uses the shared data Must guarantee: only 1 thread may be in that critical section at a time Only a thread inside a CS may determine if a thread may enter Bounded waiting (no starvation) © 2004, D. J. Foreman
Solution Proposals Turn interrupts off (not MP safe) Flag in kernel to disallow context switch (works for kernel routines too) (MP safe) loses overlapping Semaphores (MP safe) Implemented as h/w inst 80x86 has XCHG (not MP safe) Swaps RAM & register in 1 inst cycle not 1 bus cycle Busy wait or “spin lock” ..\..\552pages\slides\addenda\Classical Solutions to Mutual Exclusion.pptx © 2004, D. J. Foreman
Clever S/W-Only Solution Shared memory int flag [0..1]; int turn Process 0 code flag[0] := T; turn := 1; while (flag [1] and turn =1) do no-op; critical section flag[0] := F; © 2004, D. J. Foreman
Semaphores Sometimes called an “indivisible test and set.” In 80x86 - XCHG, swaps 1 RAM location and a register in one instruction cycle (but not one bus cycle – so not useful in multi-processor environments – unless enhanced.) Flag – global – initially 0 WAIT MOV AX,1 XCHG FLAG,AX CMP AX,1 JE WAIT - --- critical section MOV FLAG,0 © 2004, D. J. Foreman
Spin Locks While (flag); // loops until flag=0 Wastes CPU time Makes user seem “bad” © 2004, D. J. Foreman
Another Critical Section Problem Load r1,bal Load r2,amount Add r1,r2 Store r1,bal Load r1,bal Load r2,amount Sub r1,r2 Store r1,bal context-switch interrupt bal=bal + amount bal=bal - amount p1, p2 are in a race © 2004, D. J. Foreman
Locking a Critical Section While(lock) wait; lock=true Load r1,bal Load r2,amount Add r1,r2 Store r1,bal lock=false While(lock) wait; lock=true; Load r1,bal Load r2,amount Sub r1,r2 Store r1,bal lock=false bal=bal + amount bal=bal - amount © 2004, D. J. Foreman
Wait & Signal Classical definitions sem_wait – Originally was P(s) DO WHILE (s<=0) // make me wait wait; // The wait is interruptible s=s-1; sem_post - Originally was V(s) s=s+1; // tell others I'm done Remember: these must appear as ATOMIC operations to the application "s" is global © 2004, D. J. Foreman
Strategies User-only mode software Disabling interrupts H/W & O/S support © 2004, D. J. Foreman
Acceptable Solutions One process at a time in CritSec Entry decision made by entrants No indefinite wait allowed Limit to predecessors © 2004, D. J. Foreman
Additional Problems Semaphores only protect the CritSec Signaling adds need for more semaphores Classical problems: Bounded Buffer also known as Producer-Consumer Readers & Writers Readers have precedence Writers have precedence © 2004, D. J. Foreman