37
CS423: Operating Systems Design Professor Adam Bates Fall 2018 CS 423 Operating System Design: Synchronization

CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Professor Adam BatesFall 2018

CS 423 Operating System Design:

Synchronization

Page 2: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 3: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

MP1: Error check copy_*_user?

3

https://elixir.bootlin.com/linux/latest/source/include/linux/uaccess.h#L152

Page 4: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Synchronization Motivation

4

•  Whenthreadsconcurrentlyread/writesharedmemory,programbehaviorisundefined– Twothreadswritetothesamevariable;whichoneshouldwin?

•  Threadscheduleisnon-determinis>c– Behaviorchangeswhenre-runprogram

•  Compiler/hardwareinstruc>onreordering•  Mul>-wordopera>onsarenotatomic

Page 5: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Can this panic?

5

Thread1p=someComputa1on();pIni1alized=true;

Thread2while(!pIni1alized);q=someFunc1on(p);if(q!=someFunc1on(p))panic

Page 6: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Why Reordering?

6

•  Whydocompilersreorderinstruc2ons?–  Efficientcodegenera2onrequiresanalyzingcontrol/datadependency

–  Ifvariablescanspontaneouslychange,mostcompilerop2miza2onsbecomeimpossible

•  WhydoCPUsreorderinstruc2ons?– Writebuffering:allownextinstruc2ontoexecutewhilewriteisbeingcompleted

Fix:memorybarrier–  Instruc2ontocompiler/CPU– Allopsbeforebarriercompletebeforebarrierreturns– NoopaJerbarrierstartsun2lbarrierreturns

Page 7: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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!

Page 8: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Too Much Milk!

8

SOLUTION

Make your own oat milk at home

srsly tho — https://minimalistbaker.com/make-oat-milk/

Page 9: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Definitions

9

Racecondi*on:outputofaconcurrentprogramdependsontheorderofopera1onsbetweenthreads

Mutualexclusion:onlyonethreaddoesapar1cularthingata1me–  Cri*calsec*on:pieceofcodethatonlyonethreadcanexecuteatonce

Lock:preventsomeonefromdoingsomething–  Lockbeforeenteringcri1calsec1on,beforeaccessingshareddata

–  Unlockwhenleaving,a=erdoneaccessingshareddata–  Waitiflocked(allsynchroniza1oninvolveswai1ng!)

Page 10: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Too Much Milk, Try #1

10

•  Correctnessproperty– Someonebuysifneeded(liveness)– Atmostonepersonbuys(safety)

•  Try#1:leaveanoteif(!note)if(!milk){

leavenotebuymilkremovenote}

Page 11: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design 11

ThreadAleavenoteAif(!noteB){if(!milk)buymilk}removenoteA

ThreadBleavenoteBif(!noteA){if(!milk)buymilk}removenoteB

Too Much Milk, Try #2

Page 12: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 13: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Takeaways

13

•  Solu%oniscomplicated– “obvious”codeo5enhasbugs

•  Moderncompilers/architecturesreorderinstruc%ons– Makingreasoningevenmoredifficult

•  Generalizingtomanythreads/processors– Evenmorecomplex:seePeterson’salgorithm

Page 14: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 15: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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)

Page 16: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Why only Acquire/Release?

16

Why can’t we have an “Ask if Lock is Free” function?

Page 17: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design 17

Too Much Milk, Try #4

Locksallowconcurrentcodetobemuchsimpler:lock.acquire();if(!milk)buymilklock.release();

Page 18: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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();}

Page 19: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Rules for Using Locks

19

•  Lockisini)allyfree•  Alwaysacquirebeforeaccessingshareddatastructure–  Beginningofprocedure!

•  Alwaysreleasea<erfinishingwithshareddata–  Endofprocedure!– Onlythelockholdercanrelease– DONOTthrowlockforsomeoneelsetorelease

•  Neveraccessshareddatawithoutlock– Danger!

Page 20: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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;}

Page 21: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 22: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS423: Operating Systems Design

Question(s)

22

•  IftrygetreturnsNULL,doweknowthebufferisempty?

•  Ifwepolltrygetinaloop,whathappenstoathreadcallingtryput?

Page 23: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 24: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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();}

Page 25: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 26: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 27: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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();}

Page 28: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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?

Page 29: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 30: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 31: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 32: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 33: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 34: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 35: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

CS 423: Operating Systems Design

Implementing Synchronization

35

Interrupt Disable Atomic Read/Modify/Write Instructions

Hardware InterruptsMultiple Processors

Semaphores Locks Condition Variables

Concurrent Applications

Page 36: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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

Page 37: CS 423 Operating System Design: Synchronization · Synchronization Roadmap 14 Shared Objects Synchronization Variables Atomic Instructions Hardware Interrupt Disable Bounded Bu!er

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(); }