Upload
others
View
17
Download
0
Embed Size (px)
Citation preview
CS423: Operating Systems Design
Professor Adam BatesFall 2018
CS 423 Operating System Design:
Synchronization
CS 423: Operating Systems Design 2
• Learning Objectives: • Understand different primitives for synchronization at
the operating system layer • Announcements:
• C4 weekly summaries! Due Friday (any time zone) • MP1 is out! Due Feb 20 (any time zone)• CS Instructional Cloud is back online
Goals for Today
Reminder: Please put away devices at the start of class
CS423: Operating Systems Design
MP1: Error check copy_*_user?
3
https://elixir.bootlin.com/linux/latest/source/include/linux/uaccess.h#L152
CS423: Operating Systems Design
Synchronization Motivation
4
• Whenthreadsconcurrentlyread/writesharedmemory,programbehaviorisundefined– Twothreadswritetothesamevariable;whichoneshouldwin?
• Threadscheduleisnon-determinis>c– Behaviorchangeswhenre-runprogram
• Compiler/hardwareinstruc>onreordering• Mul>-wordopera>onsarenotatomic
CS423: Operating Systems Design
Can this panic?
5
Thread1p=someComputa1on();pIni1alized=true;
Thread2while(!pIni1alized);q=someFunc1on(p);if(q!=someFunc1on(p))panic
CS423: Operating Systems Design
Why Reordering?
6
• Whydocompilersreorderinstruc2ons?– Efficientcodegenera2onrequiresanalyzingcontrol/datadependency
– Ifvariablescanspontaneouslychange,mostcompilerop2miza2onsbecomeimpossible
• WhydoCPUsreorderinstruc2ons?– Writebuffering:allownextinstruc2ontoexecutewhilewriteisbeingcompleted
Fix:memorybarrier– Instruc2ontocompiler/CPU– Allopsbeforebarriercompletebeforebarrierreturns– NoopaJerbarrierstartsun2lbarrierreturns
CS423: Operating Systems Design
Too Much Milk!
7
PersonA PersonB
12:30 Lookinfridge.Outofmilk.
12:35 Leaveforstore.
12:40 Arriveatstore. Lookinfridge.Outofmilk.
12:45 Buymilk. Leaveforstore.
12:50 Arrivehome,putmilkaway. Arriveatstore.
12:55 Buymilk.
1:00 Arrivehome,putmilkaway.Ohno!
CS423: Operating Systems Design
Too Much Milk!
8
SOLUTION
Make your own oat milk at home
srsly tho — https://minimalistbaker.com/make-oat-milk/
CS423: Operating Systems Design
Definitions
9
Racecondi*on:outputofaconcurrentprogramdependsontheorderofopera1onsbetweenthreads
Mutualexclusion:onlyonethreaddoesapar1cularthingata1me– Cri*calsec*on:pieceofcodethatonlyonethreadcanexecuteatonce
Lock:preventsomeonefromdoingsomething– Lockbeforeenteringcri1calsec1on,beforeaccessingshareddata
– Unlockwhenleaving,a=erdoneaccessingshareddata– Waitiflocked(allsynchroniza1oninvolveswai1ng!)
CS423: Operating Systems Design
Too Much Milk, Try #1
10
• Correctnessproperty– Someonebuysifneeded(liveness)– Atmostonepersonbuys(safety)
• Try#1:leaveanoteif(!note)if(!milk){
leavenotebuymilkremovenote}
CS423: Operating Systems Design 11
ThreadAleavenoteAif(!noteB){if(!milk)buymilk}removenoteA
ThreadBleavenoteBif(!noteA){if(!milk)buymilk}removenoteB
Too Much Milk, Try #2
CS423: Operating Systems Design
Too Much Milk, Try #3
12
ThreadAleavenoteAwhile(noteB)//Xdonothing;if(!milk)buymilk;removenoteA
ThreadBleavenoteBif(!noteA){//Yif(!milk)buymilk}removenoteB
CanguaranteeatXandYthateither:(i) Safeformetobuy(ii) Otherwillbuy,oktoquit
CS423: Operating Systems Design
Takeaways
13
• Solu%oniscomplicated– “obvious”codeo5enhasbugs
• Moderncompilers/architecturesreorderinstruc%ons– Makingreasoningevenmoredifficult
• Generalizingtomanythreads/processors– Evenmorecomplex:seePeterson’salgorithm
CS423: Operating Systems Design
Synchronization Roadmap
14
Shared Objects
Synchronization Variables
Atomic Instructions
Hardware
Interrupt Disable
Bounded Buffer
Multiple Processors
Semaphores Locks
Test-and-Set
Barrier
Hardware Interrupts
Condition Variables
Concurrent Applications
CS423: Operating Systems Design
Locks
15
• Lock::acquire– waitun0llockisfree,thentakeit
• Lock::release– releaselock,wakingupanyonewai0ngforit
1. Atmostonelockholderata0me(safety)2. Ifnooneholding,acquiregetslock(progress)3. Ifalllockholdersfinishandnohigherpriority
waiters,waitereventuallygetslock(progress)
CS423: Operating Systems Design
Why only Acquire/Release?
16
Why can’t we have an “Ask if Lock is Free” function?
CS423: Operating Systems Design 17
Too Much Milk, Try #4
Locksallowconcurrentcodetobemuchsimpler:lock.acquire();if(!milk)buymilklock.release();
CS423: Operating Systems Design
Ex: Lock Malloc/Free
18
char*malloc(n){heaplock.acquire();p=allocatememoryheaplock.release();returnp;}
voidfree(char*p){heaplock.acquire();putpbackonfreelistheaplock.release();}
CS423: Operating Systems Design
Rules for Using Locks
19
• Lockisini)allyfree• Alwaysacquirebeforeaccessingshareddatastructure– Beginningofprocedure!
• Alwaysreleasea<erfinishingwithshareddata– Endofprocedure!– Onlythelockholdercanrelease– DONOTthrowlockforsomeoneelsetorelease
• Neveraccessshareddatawithoutlock– Danger!
CS423: Operating Systems Design
Will this Code Work?
20
if(p==NULL){lock.acquire();if(p==NULL){p=newP();}lock.release();}usep->field1
newP(){p=malloc(sizeof(p));p->field1=…p->field2=…returnp;}
CS423: Operating Systems Design
Ex: Thread-Safe Bounded Queue
21
tryget(){item=NULL;lock.acquire();if(front<tail){item=buf[front%MAX];front++;}lock.release();returnitem;}
tryput(item){lock.acquire();if((tail–front)<size){buf[tail%MAX]=item;tail++;}lock.release();}
IniJally:front=tail=0;lock=FREE;MAXisbuffercapacity
CS423: Operating Systems Design
Question(s)
22
• IftrygetreturnsNULL,doweknowthebufferisempty?
• Ifwepolltrygetinaloop,whathappenstoathreadcallingtryput?
CS423: Operating Systems Design
Condition Variables• Waiting inside a critical section
• Called only when holding a lock
• CV::Wait — atomically release lock and relinquish processor
• Reacquire the lock when wakened
• CV::Signal — wake up a waiter, if any
• CV::Broadcast — wake up all waiters, if any
23
CS423: Operating Systems Design
Condition Variables
24
methodThatWaits() { lock.acquire(); // Read/write shared state
while (!testSharedState()) { cv.wait(&lock); }
// Read/write shared state lock.release();}
methodThatSignals() { lock.acquire(); // Read/write shared state // If testSharedState is now true cv.signal(&lock);
// Read/write shared state lock.release();}
CS423: Operating Systems Design 25
Ex: Bounded Queue w/ CV
get() { lock.acquire(); while (front == tail) { empty.wait(lock); } item = buf[front % MAX]; front++; full.signal(lock); lock.release(); return item;}
put(item) { lock.acquire(); while ((tail – front) == MAX) { full.wait(lock); } buf[tail % MAX] = item; tail++; empty.signal(lock); lock.release();}
Initially: front = tail = 0; MAX is buffer capacity empty/full are condition variables
CS423: Operating Systems Design
Pre/Post Conditions
26
• What is state of the bounded buffer at lock acquire? • front <= tail • front + MAX >= tail
• These are also true on return from wait
• And at lock release
• Allows for proof of correctness
CS423: Operating Systems Design
Pre/Post Conditions
27
methodThatWaits() { lock.acquire(); // Pre-condition: State is consistent
// Read/write shared state
while (!testSharedState()) { cv.wait(&lock); } // WARNING: shared state may // have changed! But // testSharedState is TRUE // and pre-condition is true
// Read/write shared state lock.release();}
methodThatSignals() { lock.acquire(); // Pre-condition: State is consistent
// Read/write shared state // If testSharedState is now true cv.signal(&lock);
// NO WARNING: signal keeps lock
// Read/write shared state lock.release();}
CS423: Operating Systems Design
Condition Variables
28
• ALWAYS hold lock when calling wait, signal, broadcast • Condition variable is sync FOR shared state • ALWAYS hold lock when accessing shared state
• Condition variable is memoryless • If signal when no one is waiting, no op • If wait before signal, waiter wakes up
• Wait atomically releases lock • What if wait, then release? • What if release, then wait?
CS423: Operating Systems Design
Condition Variables
29
• When a thread is woken up from wait, it may not run immediately
• Signal/broadcast put thread on ready list • When lock is released, anyone might acquire it
• Wait MUST be in a loop while (needToWait()) { condition.Wait(lock); }
• Simplifies implementation • Of condition variables and locks • Of code that uses condition variables and locks
CS423: Operating Systems Design
Mesa vs. Hoare Semantics• Mesa
• Signal puts waiter on ready list
• Signaller keeps lock and processor
• Hoare
• Signal gives processor and lock to waiter
• When waiter finishes, processor/lock given back to signaller
• Nested signals possible!
30
CS423: Operating Systems Design
FIFO Bounded Queue(Hoare Semantics)
31
get() { lock.acquire(); if (front == tail) { empty.wait(lock); } item = buf[front % MAX]; front++; full.signal(lock); lock.release(); return item;}
put(item) { lock.acquire(); if ((tail – front) == MAX) { full.wait(lock); } buf[last % MAX] = item; last++; empty.signal(lock); // CAREFUL: someone else ran lock.release();}
Initially: front = tail = 0; MAX is buffer capacity empty/full are condition variables
CS423: Operating Systems Design
FIFO Bounded Queue(Mesa Semantics)
• Create a condition variable for every waiter
• Queue condition variables (in FIFO order)
• Signal picks the front of the queue to wake up
• CAREFUL if spurious wakeups!
•Easily extends to case where queue is LIFO, priority, priority donation, …
•With Hoare semantics, not as easy
32
CS423: Operating Systems Design
Synchronization Best Practices
33
• Identify objects or data structures that can be accessed by multiple threads concurrently
• Add locks to object/module • Grab lock on start to every method/procedure • Release lock on finish
• If need to wait • while(needToWait()) { condition.Wait(lock); } • Do not assume when you wake up, signaller just ran
• If do something that might wake someone up • Signal or Broadcast
• Always leave shared state variables in a consistent state • When lock is released, or when waiting
CS423: Operating Systems Design
Remember the rules…• Use consistent structure
• Always use locks and condition variables
• Always acquire lock at beginning of procedure, release at end
• Always hold lock when using a condition variable
• Always wait in while loop
• Never spin in sleep()
34
CS 423: Operating Systems Design
Implementing Synchronization
35
Interrupt Disable Atomic Read/Modify/Write Instructions
Hardware InterruptsMultiple Processors
Semaphores Locks Condition Variables
Concurrent Applications
CS423: Operating Systems Design
• Take 1: using memory load/store
• See too much milk solution/Peterson’s algorithm
• Take 2:
• Lock::acquire()
• Lock::release()
36
Implementing Synchronization
CS423: Operating Systems Design
Lock Implementation for Uniprocessor?
37
Lock::acquire() { disableInterrupts(); if (value == BUSY) { waiting.add(myTCB); myTCB->state = WAITING; next = readyList.remove(); switch(myTCB, next); myTCB->state = RUNNING; } else { value = BUSY; } enableInterrupts(); }
Lock::release() { disableInterrupts(); if (!waiting.Empty()) { next = waiting.remove(); next->state = READY; readyList.add(next); } else { value = FREE;
} enableInterrupts(); }