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

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

Jul 20, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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(); }