CS162 Operating Systems and Systems Programming Lecture 8

CS162 Operating Systems and Systems Programming Lecture 8

Review: Synchronization problem with Threads CS162 • One thread per transaction, each running: Operating Systems and Deposit(acctId, amount) { Systems Programming acct = GetAccount(actId); /* May use disk I/O */ acct->balance += amount; Lecture 8 StoreAccount(acct); /* Involves disk I/O */ } Locks, Semaphores, Monitors, • Unfortunately, shared state can get corrupted: and Thread 1 Thread 2 load r1, acct->balance Quick Intro to Scheduling load r1, acct->balance add r1, amount2 September 23rd, 2015 store r1, acct->balance add r1, amount1 Prof. John Kubiatowicz store r1, acct->balance http://cs162.eecs.Berkeley.edu • Atomic Operation: an operation that always runs to completion or not at all – It is indivisible: it cannot be stopped in the middle and state cannot be modified by someone else in the middle 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.2 Review: Too Much Milk Solution #3 Review: Too Much Milk: Solution #4 • Here is a possible two-note solution: • Suppose we have some sort of implementation of a Thread A Thread B lock (more in a moment). leave note A; leave note B; – Acquire(&mylock) – wait until lock is free, then grab while (note B) {\\X if (noNote A) {\\Y – Release(&mylock) – Unlock, waking up anyone waiting do nothing; if (noMilk) { } buy milk; – These must be atomic operations – if two threads are if (noMilk) { } waiting for the lock and both see it’s free, only one buy milk; } succeeds to grab the lock } remove note B; remove note A; • Then, our milk problem is easy: • Does this work? Yes. Both can guarantee that: Acquire(&milklock); – It is safe to buy, or if (nomilk) – Other will buy, ok to quit buy milk; Release(&milklock); • At X: – if no note B, safe for A to buy, • Once again, section of code between Acquire() and Release() called a “Critical Section” – otherwise wait to find out what will happen • Of course, you can make this even simpler: suppose • At Y: you are out of ice cream instead of milk – if no note A, safe for B to buy – Skip the test since you always need more ice cream. – Otherwise, A is either buying or waiting for B to quit 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.3 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.4 Goals for Today How to implement Locks? • Lock: prevents someone from doing something • Explore several implementations of locks – Lock before entering critical section and • Continue with Synchronization Abstractions before accessing shared data – Semaphores, Monitors, and Condition variables – Unlock when leaving, after accessing shared data – Wait if locked • Very Quick Introduction to scheduling » Important idea: all synchronization involves waiting » Should sleep if waiting for a long time • Atomic Load/Store: get solution like Milk #3 – Looked at this last lecture – Pretty complex and error prone • Hardware Lock instruction – Is this a good idea? – What about putting a task to sleep? » How do you handle the interface between the hardware and scheduler? Note: Some slides and/or pictures in the following are – Complexity? adapted from slides ©2005 Silberschatz, Galvin, and GagneGagne. » Done in the Intel 432 Many slides generated from my lecture notes by Kubiatowicz. » Each feature makes hardware more complex and slow 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.5 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.6 Naïve use of Interrupt Enable/Disable Better Implementation of Locks by Disabling Interrupts • How can we build multi-instruction atomic operations? • Key idea: maintain a lock variable and impose mutual – Recall: dispatcher gets control in two ways. exclusion only during operations on that variable » Internal: Thread does something to relinquish the CPU » External: Interrupts cause dispatcher to take CPU – On a uniprocessor, can avoid context-switching by: int value = FREE; » Avoiding internal events (although virtual memory tricky) » Preventing external events by disabling interrupts Acquire() { Release() { • Consequently, naïve Implementation of locks: disable interrupts; disable interrupts; if (value == BUSY) { if (anyone on wait queue) { LockAcquire { disable Ints; } put thread on wait queue; take thread off wait queue LockRelease { enable Ints; } Go to sleep(); Place on ready queue; • Problems with this approach: // Enable interrupts? } else { } else { value = FREE; – Can’t let user do this! Consider following: } LockAcquire(); value = BUSY; enable interrupts; While(TRUE) {;} } } – Real-Time system—no guarantees on timing! enable interrupts; » Critical Sections might be arbitrarily long } – What happens with I/O or other important events? » “Reactor about to meltdown. Help?” 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.7 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.8 New Lock Implementation: Discussion Interrupt re-enable in going to sleep • Why do we need to disable interrupts at all? • What about re-enabling ints when going to sleep? – Avoid interruption between checking and setting lock value Acquire() { – Otherwise two threads could think that they both have lock disable interrupts; if (value == BUSY) { Acquire() { Enable Position disable interrupts; Enable Position put thread on wait queue; if (value == BUSY) { Enable Position Go to sleep(); put thread on wait queue; } else { Go to sleep(); value = BUSY; // Enable interrupts? Critical } } else { Section enable interrupts; value = BUSY; } } • Before Putting thread on the wait queue? enable interrupts; – Release can check the queue and not wake up thread } • After putting the thread on the wait queue • Note: unlike previous solution, the critical section – Release puts the thread on the ready queue, but the (inside Acquire()) is very short thread still thinks it needs to go to sleep – User of lock can take as long as they like in their own critical section: doesn’t impact global machine behavior – Misses wakeup and still holds lock (deadlock!) – Critical interrupts taken in time! • Want to put it after sleep(). But – how? 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.9 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.10 How to Re-enable After Sleep()? Administrivia • In scheduler, since interrupts are disabled when you • First Checkpoint due this Friday 11:59pm PST call sleep: – Yes this is graded! – Responsibility of the next thread to re-enable ints – Assume design document is high level! – When the sleeping thread wakes up, returns to acquire » You should think of this as a document for a manager (your TA) and re-enables interrupts • Design review Thread A Thread B – High-level discussion of your approach . » What will you modify? . » What algorithm will you use? disable ints » How will things be linked together, etc. sleep » Do not need final design (complete with all semicolons!) sleep return – You will be asked about testing enable ints » Understand testing framework » Are there things you are doing that are not tested by the tests we . give you? . • Do your own work! disable int – Please do not try to find solutions from previous terms sleep – We will be look out for this… sleep return • Basic semaphores work in PintOS! enable ints – However, you will need to implement priority scheduling behavior . both in semaphore and ready queue . 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.11 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.12 Atomic Read-Modify-Write instructions Examples of Read-Modify-Write • test&set (&address) { /* most architectures */ • Problems with previous solution: result = M[address]; M[address] = 1; – Can’t give lock implementation to users return result; } – Doesn’t work well on multiprocessor • swap (&address, register) { /* x86 */ temp = M[address]; » Disabling interrupts on all processors requires messages M[address] = register; and would be very time consuming register = temp; } • Alternative: atomic instruction sequences • compare&swap (&address, reg1, reg2) { /* 68000 */ – These instructions read a value from memory and write if (reg1 == M[address]) { M[address] = reg2; a new value atomically return success; } else { – Hardware is responsible for implementing this correctly return failure; » on both uniprocessors (not too hard) } } » and multiprocessors (requires help from cache coherence • load-linked&store conditional(&address) { protocol) /* R4000, alpha */ loop: – Unlike disabling interrupts, can be used on both ll r1, M[address]; uniprocessors and multiprocessors movi r2, 1; /* Can do arbitrary comp */ sc r2, M[address]; beqz r2, loop; } 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.13 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.14 Using of Compare&Swap for queues Implementing Locks with test&set • compare&swap (&address, reg1, reg2) { /* 68000 */ if (reg1 == M[address]) { • Another flawed, but simple solution: M[address] = reg2; return success; int value = 0; // Free } else { return failure; Acquire() { } while (test&set(value)); // while busy } } Release() { Here is an atomic add to linked-list function: value = 0; addToQueue(&object) { } do { // repeat until no conflict • Simple explanation: ld r1, M[root] // Get ptr to current head st r1, M[object] // Save link in new object – If lock is free, test&set reads 0 and sets value=1, so } until (compare&swap(&root,r1,object)); lock is now busy. It returns 0 so while exits. } root next next – If lock is busy, test&set reads 1 and sets value=1 (no change). It returns 1, so while loop continues next – When we set value = 0, someone else can get lock New • Busy-Waiting: thread consumes cycles while waiting Object 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015 Lec 8.15 9/23/15 Kubiatowicz CS162 ©UCB Fall 2015

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    12 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