cs 423 operating system design synchronization
play

CS 423 Operating System Design: Synchronization Professor Adam - PowerPoint PPT Presentation

CS 423 Operating System Design: Synchronization Professor Adam Bates Fall 2018 CS423: Operating Systems Design Goals for Today Learning Objectives: Understand different primitives for synchronization at the operating system layer


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

  2. Goals for Today • 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 Reminder : Please put away devices at the start of class CS 423: Operating Systems Design 2

  3. MP1: Error check copy_*_user? https://elixir.bootlin.com/linux/latest/source/include/linux/ uaccess.h#L152 CS423: Operating Systems Design 3

  4. Synchronization Motivation • When threads concurrently read/write shared memory, program behavior is undefined – Two threads write to the same variable; which one should win? • Thread schedule is non-determinis>c – Behavior changes when re-run program • Compiler/hardware instruc>on reordering • Mul>-word opera>ons are not atomic CS423: Operating Systems Design 4

  5. Can this panic? Thread 1 Thread 2 p = someComputa1on(); while (!pIni1alized) pIni1alized = true; ; q = someFunc1on(p); if (q != someFunc1on(p)) panic CS423: Operating Systems Design 5

  6. Why Reordering? • Why do compilers reorder instruc2ons? – Efficient code genera2on requires analyzing control/ data dependency – If variables can spontaneously change, most compiler op2miza2ons become impossible • Why do CPUs reorder instruc2ons? – Write buffering: allow next instruc2on to execute while write is being completed Fix: memory barrier – Instruc2on to compiler/CPU – All ops before barrier complete before barrier returns – No op aJer barrier starts un2l barrier returns CS423: Operating Systems Design 6

  7. Too Much Milk! Person A Person B 12:30 Look in fridge. Out of milk. 12:35 Leave for store. 12:40 Arrive at store. Look in fridge. Out of milk. 12:45 Buy milk. Leave for store. 12:50 Arrive home, put milk away. Arrive at store. 12:55 Buy milk. 1:00 Arrive home, put milk away. Oh no! CS423: Operating Systems Design 7

  8. Too Much Milk! SOLUTION Make your own oat milk at home srsly tho — https://minimalistbaker.com/make-oat-milk/ CS423: Operating Systems Design 8

  9. Definitions Race condi*on: output of a concurrent program depends on the order of opera1ons between threads Mutual exclusion: only one thread does a par1cular thing at a 1me – Cri*cal sec*on: piece of code that only one thread can execute at once Lock: prevent someone from doing something – Lock before entering cri1cal sec1on, before accessing shared data – Unlock when leaving, a=er done accessing shared data – Wait if locked (all synchroniza1on involves wai1ng!) CS423: Operating Systems Design 9

  10. Too Much Milk, Try #1 • Correctness property – Someone buys if needed (liveness) – At most one person buys (safety) • Try #1: leave a note if (!note) if (!milk) { leave note buy milk remove note } CS423: Operating Systems Design 10

  11. Too Much Milk, Try #2 Thread A Thread B leave note A leave note B if (!note B) { if (!noteA) { if (!milk) if (!milk) buy milk buy milk } } remove note A remove note B CS423: Operating Systems Design 11

  12. Too Much Milk, Try #3 Thread A Thread B leave note A leave note B while (note B) // X if (!noteA) { // Y do nothing; if (!milk) if (!milk) buy milk buy milk; } remove note A remove note B Can guarantee at X and Y that either: (i) Safe for me to buy (ii) Other will buy, ok to quit CS423: Operating Systems Design 12

  13. Takeaways • Solu%on is complicated – “obvious” code o5en has bugs • Modern compilers/architectures reorder instruc%ons – Making reasoning even more difficult • Generalizing to many threads/processors – Even more complex: see Peterson’s algorithm CS423: Operating Systems Design 13

  14. Synchronization Roadmap Concurrent Applications Shared Objects Bounded Bu fg er Barrier Synchronization Variables Condition Variables Semaphores Locks Atomic Instructions Interrupt Disable Test-and-Set Hardware Multiple Processors Hardware Interrupts CS423: Operating Systems Design 14

  15. Locks • Lock::acquire – wait un0l lock is free, then take it • Lock::release – release lock, waking up anyone wai0ng for it 1. At most one lock holder at a 0me (safety) 2. If no one holding, acquire gets lock (progress) 3. If all lock holders finish and no higher priority waiters, waiter eventually gets lock (progress) CS423: Operating Systems Design 15

  16. Why only Acquire/Release? Why can’t we have an “Ask if Lock is Free” function? CS423: Operating Systems Design 16

  17. Too Much Milk, Try #4 Locks allow concurrent code to be much simpler: lock.acquire(); if (!milk) buy milk lock.release(); CS423: Operating Systems Design 17

  18. Ex: Lock Malloc/Free char *malloc (n) { void free(char *p) { heaplock.acquire(); heaplock.acquire(); p = allocate memory put p back on free list heaplock.release(); heaplock.release(); return p; } } CS423: Operating Systems Design 18

  19. Rules for Using Locks • Lock is ini)ally free • Always acquire before accessing shared data structure – Beginning of procedure! • Always release a<er finishing with shared data – End of procedure! – Only the lock holder can release – DO NOT throw lock for someone else to release • Never access shared data without lock – Danger! CS423: Operating Systems Design 19

  20. Will this Code Work? if (p == NULL) { newP() { lock.acquire(); p = malloc(sizeof(p)); if (p == NULL) { p->field1 = … p = newP(); p->field2 = … } return p; lock.release(); } } use p->field1 CS423: Operating Systems Design 20

  21. Ex: Thread-Safe Bounded Queue tryget() { tryput(item) { item = NULL; lock.acquire(); lock.acquire(); if ((tail – front) < size) { if (front < tail) { buf[tail % MAX] = item; item = buf[front % MAX]; tail++; front++; } } lock.release(); lock.release(); } return item; } IniJally: front = tail = 0; lock = FREE; MAX is buffer capacity CS423: Operating Systems Design 21

  22. Question(s) • If tryget returns NULL, do we know the buffer is empty? • If we poll tryget in a loop, what happens to a thread calling tryput? CS423: Operating Systems Design 22

  23. 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 CS423: Operating Systems Design 23

  24. Condition Variables methodThatSignals() { methodThatWaits() { lock.acquire(); lock.acquire(); // Read/write shared state // Read/write shared state // If testSharedState is now true while (!testSharedState()) { cv.signal(&lock); cv.wait(&lock); } // Read/write shared state // Read/write shared state lock.release(); lock.release(); } } CS423: Operating Systems Design 24

  25. Ex: Bounded Queue w/ CV get() { put(item) { lock.acquire(); lock.acquire(); while (front == tail) { while ((tail – front) == MAX) { empty.wait(lock); full.wait(lock); } } item = buf[front % MAX]; buf[tail % MAX] = item; front++; tail++; full.signal(lock); empty.signal(lock); lock.release(); lock.release(); return item; } } Initially: front = tail = 0; MAX is buffer capacity empty/full are condition variables CS423: Operating Systems Design 25

  26. Pre/Post Conditions • 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 26

  27. Pre/Post Conditions methodThatWaits() { methodThatSignals() { lock.acquire(); lock.acquire(); // Pre-condition: State is consistent // Pre-condition: State is consistent // Read/write shared state // Read/write shared state while (!testSharedState()) { // If testSharedState is now true cv.wait(&lock); cv.signal(&lock); } // WARNING: shared state may // NO WARNING: signal keeps lock // have changed! But // testSharedState is TRUE // Read/write shared state // and pre-condition is true lock.release(); } // Read/write shared state lock.release(); } CS423: Operating Systems Design 27

  28. Condition Variables • 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 28

  29. Condition Variables • 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 29

Recommend


More recommend