Synchronization: Locks, Semaphores

Synchronization: Locks, Semaphores

Review: Too Much Milk Solution #3 • Here is a possible two-note solution: CS162 Thread A Thread B Operating Systems and leave note A; leave note B; while (note B) {\\X if (noNote A) {\\Y Systems Programming do nothing; if (noMilk) { }buy milk; Lecture 8 if (noMilk) {} buy milk; } } remove note B; Locks, Semaphores, Monitors remove note A; • Does this work? Yes. Both can guarantee that: – It is safe to buy, or February 14th, 2019 – Other will buy, ok to quit •At X: Prof. John Kubiatowicz – If no note B, safe for A to buy, http://cs162.eecs.Berkeley.edu – Otherwise wait to find out what will happen •At Y: – If no note A, safe for B to buy – Otherwise, A is either buying or waiting for B to quit 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.2 Review: Solution #3 discussion Too Much Milk: Solution #4 • Our solution protects a single “Critical-Section” piece of • Suppose we have some sort of implementation of a lock code for each thread: – lock.Acquire() – wait until lock is free, then grab if (noMilk) { buy milk; – lock.Release() – Unlock, waking up anyone waiting } – These must be atomic operations – if two threads are waiting • Solution #3 works, but it’s really unsatisfactory for the lock and both see it’s free, only one succeeds to grab – Really complex – even for this simple an example the lock » Hard to convince yourself that this really works • Then, our milk problem is easy: – A’s code is different from B’s – what if lots of threads? milklock.Acquire(); » Code would have to be slightly different for each thread if (nomilk) – While A is waiting, it is consuming CPU time buy milk; » This is called “busy-waiting” milklock.Release(); • There’s a better way • Once again, section of code between Acquire() and – Have hardware provide higher-level primitives than atomic Release() called a “Critical Section” load & store • Of course, you can make this even simpler: suppose you – Build even higher-level programming abstractions on this hardware support are out of ice cream instead of milk – Skip the test since you always need more ice cream ;-) 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.3 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.4 Where are we going with synchronization? Goals for Today • We are going to implement various higher-level • Explore several implementations of locks synchronization primitives using atomic operations • Continue with Synchronization Abstractions – Everything is pretty painful if only atomic primitives are load and store – Semaphores, Monitors, and Condition variables – Need to provide primitives useful at user-level • Very Quick Introduction to scheduling Programs Shared Programs Higher- level Locks Semaphores Monitors Send/Receive API Load/Store Disable Ints Test&Set Hardware Note: Some slides and/or pictures in the following are Compare&Swap adapted from slides ©2005 Silberschatz, Galvin, and GagneGagne. 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.5 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.6 How to Implement Locks? Naïve use of Interrupt Enable/Disable • Lock: prevents someone from doing something • How can we build multi-instruction atomic operations? – Lock before entering critical section and – Recall: dispatcher gets control in two ways. before accessing shared data » Internal: Thread does something to relinquish the CPU – Unlock when leaving, after accessing shared data » External: Interrupts cause dispatcher to take CPU – On a uniprocessor, can avoid context-switching by: – Wait if locked » Avoiding internal events (although virtual memory tricky) » Important idea: all synchronization involves waiting » Preventing external events by disabling interrupts » Should sleep if waiting for a long time • Consequently, naïve Implementation of locks: • Atomic Load/Store: get solution like Milk #3 LockAcquire { disable Ints; } – Pretty complex and error prone LockRelease { enable Ints; } • Problems with this approach: • Hardware Lock instruction – Can’t let user do this! Consider following: – Is this a good idea? LockAcquire(); – What about putting a task to sleep? While(TRUE) {;} » What is the interface between the hardware and scheduler? – Real-Time system—no guarantees on timing! » Critical Sections might be arbitrarily long – Complexity? – What happens with I/O or other important events? » Done in the Intel 432 » “Reactor about to meltdown. Help?” » Each feature makes HW more complex and slow 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.7 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.8 Better Implementation of Locks by Disabling Interrupts New Lock Implementation: Discussion • Why do we need to disable interrupts at all? • Key idea: maintain a lock variable and impose mutual – Avoid interruption between checking and setting lock value exclusion only during operations on that variable – Otherwise two threads could think that they both have lock Acquire() { int value = FREE; disable interrupts; if (value == BUSY) { Acquire() { Release() { put thread on wait queue; disable interrupts; disable interrupts; Go to sleep(); Critical if (value == BUSY) { if (anyone on wait queue) { // Enable interrupts? put thread on wait queue; take thread off wait queue } else { Section Go to sleep(); Place on ready queue; value = BUSY; // Enable interrupts? } else { } value = FREE; } else { enable interrupts; } value = BUSY; enable interrupts; } } } • Note: unlike previous solution, the critical section (inside enable interrupts; Acquire()) is very short } – User of lock can take as long as they like in their own critical section: doesn’t impact global machine behavior – Critical interrupts taken in time! 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.9 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.10 Interrupt Re-enable in Going to Sleep Interrupt Re-enable in Going to Sleep • What about re-enabling ints when going to sleep? • What about re-enabling ints when going to sleep? Acquire() { Acquire() { disable interrupts; disable interrupts; if (value == BUSY) { if (value == BUSY) { put thread on wait queue; Enable Position put thread on wait queue; Go to sleep(); Go to sleep(); } else { } else { value = BUSY; value = BUSY; } } enable interrupts; enable interrupts; } } • Before Putting thread on the wait queue? 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.11 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.12 Interrupt Re-enable in Going to Sleep Interrupt Re-enable in Going to Sleep • What about re-enabling ints when going to sleep? • What about re-enabling ints when going to sleep? Acquire() { Acquire() { disable interrupts; disable interrupts; if (value == BUSY) { if (value == BUSY) { Enable Position put thread on wait queue; Enable Position put thread on wait queue; Go to sleep(); Go to sleep(); } else { } else { value = BUSY; value = BUSY; } } enable interrupts; enable interrupts; } } • Before Putting thread on the wait queue? • Before Putting thread on the wait queue? – Release can check the queue and not wake up thread – Release can check the queue and not wake up thread • After putting the thread on the wait queue 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.13 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.14 Interrupt Re-enable in Going to Sleep Interrupt Re-enable in Going to Sleep • What about re-enabling ints when going to sleep? • What about re-enabling ints when going to sleep? Acquire() { Acquire() { disable interrupts; disable interrupts; if (value == BUSY) { if (value == BUSY) { Enable Position put thread on wait queue; put thread on wait queue; Go to sleep(); Enable Position Go to sleep(); } else { } else { value = BUSY; value = BUSY; } } enable interrupts; enable interrupts; } } • Before Putting thread on the wait queue? • Before Putting thread on the wait queue? – Release can check the queue and not wake up thread – Release can check the queue and not wake up thread • After putting the thread on the wait queue • After putting the thread on the wait queue – Release puts the thread on the ready queue, but the thread – Release puts the thread on the ready queue, but the thread still thinks it needs to go to sleep still thinks it needs to go to sleep – Misses wakeup and still holds lock (deadlock!) – Misses wakeup and still holds lock (deadlock!) • Want to put it after sleep(). But – how? 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.15 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.16 How to Re-enable After Sleep()? Administrivia • In scheduler, since interrupts are disabled when you call • Midterm Thursday 2/28 sleep: – No class on day of midterm – Responsibility of the next thread to re-enable ints – 8-10PM – no conflict with data science! – When the sleeping thread wakes up, returns to acquire and • Project 1 Design Document due next Wednesday 2/20 re-enables interrupts Thread A Thread B • Project 1 Design reviews upcoming . – High-level discussion of your approach . » What will you modify? disable ints » What algorithm will you use? sleep » How will things be linked together, etc. sleep return enable ints » Do not need final design (complete with all semicolons!) . – You will be asked about testing . » Understand testing framework . » Are there things you are doing that are not tested by tests we give disable int you? sleep • Do your own work! sleep return enable ints – Please do not try to find solutions from previous terms . – We will be on the look out for anyone doing this…today . 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.17 2/14/19 Kubiatowicz CS162 ©UCB Spring 2019 Lec 8.18 Atomic Read-Modify-Write Instructions Examples of Read-Modify-Write

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    11 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us