csci 4 6 730
play

CSCI [4|6] 730 Synchronization Language/Definitions: What are race - PowerPoint PPT Presentation

Process [& Thread] Synchronization Why is synchronization needed? CSCI [4|6] 730 Synchronization Language/Definitions: What are race conditions? Operating Systems What are critical sections? What are atomic operations?


  1. Process [& Thread] Synchronization • Why is synchronization needed? CSCI [4|6] 730 • Synchronization Language/Definitions: – What are race conditions? Operating Systems – What are critical sections? – What are atomic operations? • How are locks implemented? Synchronization Part 1 : The Basics Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Why does cooperation require 1,2, 3.. deposit Example Execution synchronization? • Example: Two threads: Maria Maria and Tucker Tucker share an deposit(amount) { balance = balance + amount; } account with shared variable � balance � in memory . 1. Initialization: balance = 100 • Both use deposit() deposit() : 2. Maria: deposit( 200 ) May need 2-3 registers (register/memory – deposit (Maria): register/register (stack à r/r) architecture), 3. Tucker: deposit( 10 ) separately storing amount and result. load RegisterA, 100 Deposit.c – C - Code Translated to Assembly ( abstracted ) add RegisterA, 200 store RegisterA, balance void deposit( int amount ) deposit: deposit: { load RegisterA, balance load RegisterA, balance balance = balance + amount; add RegisterA, amount deposit (Tucker): add RegisterA, amount } store RegisterA, balance store RegisterA, balance load RegisterA, 300 Time add RegisterA, 10 • Both Maria & Tucker deposit() deposit() money into account: store RegisterA, balance Memory: Memory: Memory: Memory: Memory: Memory: Memory: – Ini?aliza?on: balance = 100 \ balance = 310 balance = 300 balance = 300 balance = 100 balance = 300 balance = 100 balance = 100 – Maria: deposit( 200 ) RegisterA = 310 RegisterA = 310 RegisterA = 300 RegisterA = 100 RegisterA = 300 RegisterA = 300 RegisterA = 0 Which variables are – Tucker: deposit( 10 ) shared? Which are private? Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA

  2. What program data is (or is not) 4. Memory: 2. Memory: 3. Memory: 1. Memory: 4. Memory: 1. Memory: 2. Memory: 3. Memory: 310? Concurrency 300? balance = 100 balance = 100 balance = 300 balance = 100 balance = 100 balance = 100 balance = 110 balance = 100 110? shared? RegisterA = 100 RegisterA = 300 RegisterA = 0 RegisterA = 300 RegisterA = 100 RegisterA = 110 RegisterA = 110 RegisterA = 0 • What happens if M & T deposit the funds • Local variables are not shared (private) deposit(amount) { balance = balance + amount; } � concurrently � ? – Strategy: – Each thread has its own stack deposit: • Assume that any interleaving is possible load RegisterA, balance – Local variables are allocated on private stack – No assumption about scheduler add RegisterA, amount – Observation: When a thread is interrupted • Global variables and sta?c objects are shared content of registers are saved (and restored) by store RegisterA, balance interrupt handlers (dispatcher/context switcher) Time – Stored in the sta?c data segment, accessible by any • Initialization: balance = 100 • Maria: deposit( 200 ) threads • Tucker: deposit( 10 ) deposit (Maria): deposit (Tucker): – Pass by (variable) ‘reference’ : &data1 load RegisterA, balance M • Dynamic objects and other heap objects are T load RegisterA, balance M add RegisterA, 200 shared add RegisterA, 10 T – Allocated from heap with malloc/free or new/delete store RegisterA, balance M T store RegisterA, balance 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 Maria Hybinette, UGA Maria Hybinette, UGA Race Condition How to avoid race conditions • Results depends on the order of execu?on • Idea: Prohibit one or more threads from reading and writing shared data at the same – Result in non-determinis?c bugs, these are hard to find! • Determinis?c : Input alone determines results, i.e., the same time! ⇒ Provide Mutual Exclusion (what?) inputs always produce the same results: • Critical Section: part of a program’s memory – Example: sqrt (4) = 2 (or ‘slice”) where shared memory is • Intermi[ent – accessed – A ?me dependent “bug”? Critical Section – Slow statements may hide bugs in code void credit( int amount ) void debit( int amount ) { { – print() o`en hide bugs, consistently. They are int x = 5; int i; significantly slower than statements such as assignment printf( � Adding money � ); balance = balance - amount; statements, addi?on, and subtrac?on. balance = balance + amount; for( i = 0; i < 5; i++ ); – Beware of statements that impacts the ?ming of threads. } } Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA

  3. What We Want: THE Critical Section Problem? Mutual Exclusion (!) • Problem: Avoiding race conditions (i.e., provide mutual exclusion) is not sufficient for having Maria enters her critical section Maria leaves her critical section threads cooperate correctly (no progress) and Process Maria efficiently: – What about if no one gets into the critical section even if several threads wants to get in? (No progress at ALL!) Process Tucker – What about if someone waits outside the critical section and never gets a turn? (starvation, NOT FAIR!) 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 Maria Hybinette, UGA Maria Hybinette, UGA Critical Section Problem: THE Critical Section Properties � Proper � Synchronization Memorize • Required “Proper”?es : Required Properties: • Mutual Exclusion: – Mutual Exclusion – Progress (someone gets the CS) – Only one thread in the critical section at a time • Progress (e.g., someone gets the CS): – Bounded wai?ng (starva?on-free, eventually you will run) – Not block others out: If there are requests to enter the CS • Desirable Proper?es: It’s must allow one to proceed Available – Must not depend on threads outside critical section – Efficient: • If no one is in CS then someone must be let in … • Don’t consume substan?al resources while wai?ng (busy wait/spin – We take no reservations! wait) • Bounded waiting (starvation-free): – Fair: – Must eventually allow each waiting thread • Don’t make some processes or threads wait longer than others – to enter – Simple: Should be easy to reason about and use Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA

  4. Critical Section Problem: Need Disabling Interrupts Atomic Operations • Basics: Need atomic operations: • Kernel provides two system calls: void Aquire() { – Acquire() and – No other instructions can be interleaved (low level) disable interrupts – Release() – Completed in its entirety without interruption (no craziness) } • No preemption when interrupts are off! • Examples of atomic operations: void Release() – No clock interrupts can occur – Loads and stores of words { • Disadvantage: enable interrupts • load register1, B – unwise to give processes power to turn of } • store register2, A interrupts – Idea: Code between interrupts on uniprocessors • Never turn interrupts on again! • Disable timer interrupts, don’t do I/O – Does not work on multiprocessors • When to use?: – Special hardware instructions (later) • � load, store � in one instruction – But it may be good for kernel itself to disable interrupts for a few instructions while it is • Test&Set updating variables or lists • Compare&Swap Who do you trust? 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 Maria Hybinette, UGA Maria Hybinette, UGA Attempt 1: Shared Lock Variable Software Solutions • Assumptions: • Single shared lock variable – We have an atomic load operation (read) boolean lock = false; // lock available shared variable – We have an atomic store operation (write, assignment) void deposit(int amount) { • Notation [lock=true, lock=false] while( lock == true ) {} /* while lock is set : wait */ ; Entry CS: lock = true; /* gets the lock */ – True: means un-available (lock is set, someone has the lock) CS: balance += amount; // critical section – False: means available (e.g., lock is not set, as the CS is available, no one is in the CS) Exit CS: lock = false; /* release the lock */ } • Uses busy waiting • Does this work? – Are any of the principles violated? Does it ensure: • Mutual exclusion • Progress, and • Bounded waiting? Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA

Recommend


More recommend