csci 4 6 730 operating systems
play

CSCI [4|6] 730 Operating Systems Synchronization Part 1 : The - PDF document

CSCI [4|6] 730 Operating Systems Synchronization Part 1 : The Basics Maria Hybinette, UGA Maria Hybinette, UGA Process [& Thread] Synchronization Why is synchronization needed? Synchronization Language/Definitions: What are


  1. CSCI [4|6] 730 Operating Systems Synchronization Part 1 : The Basics Maria Hybinette, UGA Maria Hybinette, UGA Process [& Thread] Synchronization • Why is synchronization needed? • Synchronization Language/Definitions: – What are race conditions? – What are critical sections? – What are atomic operations? • How are locks implemented? Maria Hybinette, UGA Maria Hybinette, UGA

  2. Why does cooperation require synchronization? • Example: Two threads: Maria Maria and Tucker Tucker share an account with shared variable ‘ balance ’ in memory . • Both use deposit() deposit() : Deposit.c – C - Code Translated to Assembly ( abstracted ) void deposit( int amount ) deposit: { load RegisterA, balance balance = balance + amount; add RegisterA, amount } store RegisterA, balance Which variables are shared? Which are private? • Both Maria & Tucker deposit() deposit() money into account: – Initialization: balance = 100 – Maria: deposit( 200 ) Side Note: abstracted b/c may need 2-3 registers – Tucker: deposit( 10 ) depending on architecture (register/memory – register/register (stack ! r/r) architecture), separately storing amount and result. Maria Hybinette, UGA Maria Hybinette, UGA 1,2, 3.. deposit Example Execution deposit(amount) { balance = balance + amount; } 1. Initialization: balance = 100 2. Maria: deposit( 200 ) deposit (Maria): 3. Tucker: deposit( 10 ) load RegisterA, 100 add RegisterA, 200 store RegisterA, balance deposit: load RegisterA, balance deposit (Tucker): add RegisterA, amount load RegisterA, 300 store RegisterA, balance Time add RegisterA, 10 store RegisterA, balance Memory: Memory: Memory: Memory: Memory: Memory: Memory: balance = 310 balance = 300 balance = 100 balance = 300 balance = 300 balance = 100 balance = 100 RegisterA = 300 RegisterA = 300 RegisterA = 310 RegisterA = 300 RegisterA = 100 RegisterA = 310 RegisterA = 0 Maria Hybinette, UGA Maria Hybinette, UGA

  3. 3. Memory: 1. Memory: 2. Memory: 4. Memory: 1. Memory: 2. Memory: 4. Memory: 3. Memory: 310? Concurrency 300? balance = 300 balance = 100 balance = 100 balance = 100 balance = 100 balance = 100 balance = 110 balance = 100 110? RegisterA = 300 RegisterA = 300 RegisterA = 0 RegisterA = 100 RegisterA = 110 RegisterA = 0 RegisterA = 110 RegisterA = 100 • What happens if M & T deposit the funds deposit(amount) { balance = balance + amount; } “concurrently”? – Strategy: deposit: • Assume that any interleaving is possible load RegisterA, balance – No assumption about scheduler add RegisterA, amount – Observation: When a thread is interrupted content of registers are saved (and restored) by store RegisterA, balance interrupt handlers (dispatcher/context switcher) Time • Initialization: balance = 100 • Maria: deposit( 200 ) • Tucker: deposit( 10 ) deposit (Maria): deposit (Tucker): load RegisterA, balance M T load RegisterA, balance M add RegisterA, 200 add RegisterA, 10 T store RegisterA, balance M T store RegisterA, balance Maria Hybinette, UGA Maria Hybinette, UGA What program data is (or is not) shared? • Local variables are not shared (private) – Each thread has its own stack – Local variables are allocated on private stack • Global variables and static objects are shared – Stored in the static data segment, accessible by any threads – Pass by (variable) ‘reference’ : &data1 • Dynamic objects and other heap objects are shared -- Allocated from heap with malloc/free or new/delete Beware of Weird Bugs: Never pass, share, or store a pointer * to a local variable on another threads stack . (don’t allow access to private space) Maria Hybinette, UGA Maria Hybinette, UGA

  4. Race Condition • Results/Content depends on the order of execution – Who gets to it last: A race to be last. – Timing or delays determines output not the value of input variables. – Result in nondeterministic bugs, these are hard to find! • Deterministic : Inputs alone determines results, i.e., the same inputs always produce the same results – no side effects. – Example: sqrt (4) = 2 • Nondeterministic: Same input produces different results. – Example f(4) = 2 or 4 or … or … • Intermittent – – A time dependent “bug”? – Slow statements may hide bugs in code – print() often hides bugs, consistently. Print() statements are significantly slower than statements such as assignment statements, addition, and subtraction. – Lesson : Beware of statements that impacts the timing of threads. Maria Hybinette, UGA Maria Hybinette, UGA How to avoid race conditions Protect the Critical Section • Idea: Prohibit one or more threads from reading and writing shared data at the same time! ⇒ Provide Mutual Exclusion (what?) • Critical Section : part of a program’s memory (or ‘slice”) where shared memory is accessed Critical Section void credit( int amount ) void debit( int amount ) { { int x = 5; int i; printf( “ Adding money ” ); balance = balance - amount; balance = balance + amount; for( i = 0; i < 5; i++ ); } } Maria Hybinette, UGA Maria Hybinette, UGA

  5. THE Critical Section Problem? • Problem: Avoiding race conditions (i.e., provide mutual exclusion) is not sufficient for having threads cooperate correctly (no progress) and Mutual Exclusion efficiently: – What about if no one gets into the critical section even if Progress several threads wants to get in? (No progress at ALL!) – What about if someone waits outside the critical section and Bounded never gets a turn? (starvation, NOT FAIR!) Waiting Lets play with locks Maria Hybinette, UGA Maria Hybinette, UGA What We Want: Mutual Exclusion (!) Maria enters her critical section Maria leaves her critical section Process Maria Process Tucker Time Tucker is blocked, and waits Tucker enters his void deposit( int amount ) critical section Tucker leaves his { Tucker attempts to enter critical section balance = balance + amount; his critical section } Maria Hybinette, UGA Maria Hybinette, UGA

  6. Critical Section Problem: Properties Memorize Required Properties: • Mutual Exclusion: – Only one thread in the critical section at a time • Progress: – Someone gets the CS if it is available (and requests). It’s – Not block others out: If there are requests to enter the CS must Available allow one to proceed – Must not depend on threads outside critical section • If no one is in CS then someone must be let in… – We take no reservations! • Bounded waiting – Starvation-free. – Must eventually allow each waiting thread to enter Maria Hybinette, UGA Maria Hybinette, UGA THE Critical Section “ Proper ” Synchronization • Required “Proper”ties : – Mutual Exclusion – Progress (someone gets the CS) – Bounded waiting (starvation-free, eventually you will run) • Desirable Properties: – Efficient: • Don’t consume substantial resources while waiting (busy wait/spin wait) – Fair: • Don’t make some processes or threads wait longer than others – Simple: Should be easy to reason about and use Maria Hybinette, UGA Maria Hybinette, UGA

  7. Critical Section Problem: Need Atomic Operations • Basics: Need atomic operations: – Atomic : A single irreducible unit – No other instructions can be interleaved (low level) – Completed in its entirety without interruption (no craziness) • Examples of atomic operations: – Loads and stores of words are atomic • load register1, B • store register2, A – Idea: Disable action between interrupts on uniprocessors • Method 1: Disable timer interrupts , or don’t do I/O • Method 2: Special hardware instructions (later) – “load, store” in one instruction – Test&Set – Compare&Swap Maria Hybinette, UGA Maria Hybinette, UGA Disabling Interrupts • Kernel provides two system calls: void Aquire() { – Acquire() and disable interrupts – Release( ) } • No preemption when interrupts are off-line. – Preemption means you take the processor away from void Release() you. { – Disable interrupts - No clock interrupts can enable interrupts occur } • Disadvantage: – unwise to give processes power to turn of interrupts • Never turn interrupts on again! – Does not work on multiprocessors (Why?) • When to use?: – But it may be good for kernel itself to disable interrupts for a few instructions while it is Who do you trust? updating variables or lists Do you trust your kernel? Do you trust your friend ’ s kernel? Do you trust your kernel ‘ s friends? Maria Hybinette, UGA Maria Hybinette, UGA

Recommend


More recommend