Preemptive Scheduling • Scheduler select a READY process and sets it up to run for a maximum of Preemptive Scheduling and some fixed time (time-slice) Mutual Exclusion with Hardware Support • Scheduled process computes happily, oblivious to the fact that a maximum time-slice was set by the scheduler • Whenever a running process exhausts its time-slice, the scheduler needs to suspend the process and select another process to run (assuming one exists) Otto J. Anshus, Tore Larsen • To do this, the scheduler needs to be running! To make sure that no process University of Tromsø, University of Oslo computes beyond its time-slice, the scheduler needs a mechanism that (Including slides from Kai Li, Princeton University) guarantees that the scheduler itself is not suspended beyond the duration of one time-slice. A “wake-up” call is needed 05.09.03 University of Oslo, INF3150 1 05.09.03 University of Oslo, INF3150 2 Interrupts and Exceptions Software Interrupts • Interrupts and exceptions suspend the execution of the running • INT instruction thread of control, and activates some kernel routine – Ex INT 10h • Three categories of interrupts: • Explicitly issued by program – Software interrupts • Synchronous to program execution – Hardware interrupts • Goes via “interrupt vector,” at offset 4*interrupt# – Exceptions • IRET, returns to instruction immediately following INT- instruction 05.09.03 University of Oslo, INF3150 3 05.09.03 University of Oslo, INF3150 4
Hardware Interrupts Exceptions • Set by hardware components (for example timer ), and peripheral • Initiated by processor devices (for example disk) • Three types: – Fault: Faulting instruction causes exception without completing. When – Timer component, set to generate timer-interrupt at any specified thread resumes (after IRET), the faulting instruction is re-issued. For frequency! Separate unit or integral part of interrupt controller example page-fault • Asynchronous to program execution – Trap: Exception is issued after instruction completes. When thread • Non-maskable (NMI), and maskable interrupts. resumes (after IRET), the immediately following instruction is issued. May be used for debugging – NMI are processed immediately once current instruction is – Abort: Serious failure. May not indicate address of offending instruction finished. • Have used Intel terminology in this presentation. Classification, – Maskable interrupts may be permanently or temporarily masked terminology, and functionality varies among manufacturers and authors 05.09.03 University of Oslo, INF3150 5 05.09.03 University of Oslo, INF3150 6 Multiprogramming and Interrupts When to Schedule? • Overlapping computation and I/O: 1. Process created CPU – Within single thread: Non-blocking 2. Process exits I/O Timer – Among multiple threads: Also 3. Process blocks blocking I/O with scheduling Memory 4. I/O interrupt • Sharing CPU among multiple threads – Set timer interrupt to enforce 5. Timer maximum time-slice – Ensures even and fair progression of concurrent threads • Maintaining consistent kernel structures – Disable/enable interrupts cautiously in kernel 05.09.03 University of Oslo, INF3150 7 05.09.03 University of Oslo, INF3150 8
Process State Transitions U s e r L e v e l P r o c e s s e s PC Preemptive Scheduling MULTIPROGRAMMING P1 P2 P3 P4 Syscall •Uniprocessor: Interleaving (“pseudoparallelism”) KERNEL Terminate Trap Service •Multiprocessor: Overlapping (“true (call scheduler) Handler paralellism”) Scheduler Trap Return P2 BlockedQueue Running Handler dispatch Block for resource (call scheduler) P3 P4 Terminate Scheduler ReadyQueue Yield, Timer Interrupt (call scheduler) (call scheduler) Current P1 Create Dispatcher Scheduler PCB’s Running dispatch Ready Block for resource Blocked (call scheduler) Yield, Timer Interrupt (call scheduler) Create Memory resident part Ready Blocked I/O completion interrupt (Process Table) (move to ready queue) I/O completion interrupt (move to ready queue) 05.09.03 University of Oslo, INF3150 9 05.09.03 University of Oslo, INF3150 10 Implementation of Synchronization Mechanisms Hardware Support for Mutex Concurrent • Atomic memory load and store Applications – Assumed by Dijkstra (CACM 1965): Shared memory w/atomic R Shared Variables Message Passing High-Level and W operations Locks Semaphores Monitors Send/Receive Atomic API – L. Lamport, “A Fast Mutual Exclusion Algorithm,” ACM Trans. on Computer Systems, 5(1):1-11, Feb 1987. Low-Level • Disable Interrupts Load/Store Interrupt disable Test&Set Atomic Ops • Atomic read-modify-write – IBM/360: Test And Set proposed by Dirac (1963) – IBM/370: Generalized Compare And Swap (1970) Interrupt (timer or I/O completion), Scheduling, Multiprocessor 05.09.03 University of Oslo, INF3150 11 05.09.03 University of Oslo, INF3150 12
A Fast Mutual Exclusion Algorithm (Fischer) Disable Interrupts Executed by process no. i. ”While x =/= 0 do skip;” • CPU scheduling X is shared memory. Or could block? How? – Internal events <op> is an Atomic Operation. Repeat • Threads do something to relinquish the CPU await <x=0>; – External events Entry: <x := i>; • Interrupts cause rescheduling of the CPU <delay>; • Disabling interrupts until <x = i>; – Delay handling of external events use shared resource Critical • and make sure we have a safe ENTRY or EXIT Region <x := 0>; Exit We are assuming that COMMON CASE will be fast and that all processes will get through eventually 05.09.03 University of Oslo, INF3150 13 05.09.03 University of Oslo, INF3150 14 Disable Interrupts w/Busy Wait Does This Work? Acquire() { Acquire(lock) { disable interrupts; disable interrupts; Release(lock) { } User Level while (lock != FREE){ disable interrupts; enable interrupts; lock = FREE; Release() { disable interrupts; enable interrupts; enable interrupts; Spins } } } lock = BUSY; enable interrupts; • Kernel cannot let users disable interrupts } • Kernel can provide two system calls, Acquire and Release, but • We are at Kernel Level!: So why do we need to disable need ID of critical region interrupts at all? • Remember: Critical sections can be arbitrary long (no • Why do we need to enable interrupts inside the loop in preemption!) Acquire ? • Used on uni-processors, but won’t work on multiprocessors • Would this work for multiprocessors? • Why not have a “disabled” Kernel? 05.09.03 University of Oslo, INF3150 15 05.09.03 University of Oslo, INF3150 16
Atomic Read-Modify-Write Instructions Disable Interrupts w/Blocking • What we want: Test&Set (lock): Returns TRUE if lock is TRUE Acquire(lock) { Release(lock) { (closed), else returns FALSE and closes lock. disable interrupts; disable interrupts; • Exchange ( xchg , x86 architecture) while (lock == BUSY) { if (nonempty(lock_queue)) { insert(caller, lock_queue); remove(tid, lock_queue); • Swap register and memory BLOCK; insert(tid, ready_queue); • Compare and Exchange ( cmpxchg, 486 or Pentium) } else } Used to • cmpxchg d,s: If Dest = ( al,ax,eax ), Dest = SRC; lock = BUSY; lock = FREE; implement enable interrupts; else ( al,ax,eax ) = Dest enable interrupts; USER level } } locks • LOCK prefix in x86 • Load link and conditional store (MIPS, Alpha) • When must Acquire re-enable interrupts in going to sleep? • Read value in one instruction, do some operations – Before insert()? • When store, check if value has been modified. If not, ok; otherwise, Starvation – After insert(), but before block? possible, at jump back to start • Would this work on multiprocessors? least • The Butterfly multiprocessor unfairness • atomicadd : one processor can read and increment a memory location Deadlock possible because then Release can be executed by So enable inside BLOCK, and must involve while preventing other processors from accessing the location another thread right before we can do the BLOCK, and then we 05.09.03 University of Oslo, INF3150 17 05.09.03 University of Oslo, INF3150 18 Kernel simultaneously do the BLOCK, and we will never be awakened again Test&Set with Minimal Busy Waiting A Simple Solution with Test&Set CLOSED = TRUE OPEN = FALSE INITIALLY : Lock := FALSE; /* OPEN */ TAS (lock): Acquire(lock) { Release(lock) { while (TAS(lock.guard)) Acquire(lock) { {TAS := lock; while (TAS(lock.guard)) ; while (TAS(lock)) lock := TRUE;} ; Spin until if (lock.value) { if (anyone in queue) { lock = open ; enqueue the thread; dequeue a thread; } block and lock.guard:=OPEN; make it ready; %Starts here after a Release() } else lock.value:=OPEN; Release(lock) { } lock.guard:=OPEN; lock = FALSE; lock.value:=CLOSED; } } lock.guard:=OPEN; NB: Lock is kept closed! } • Waste CPU time (busy waiting by all threads) • Two levels: Get inside a mutex, then check resource availability • Low priority threads may never get a chance to run (starvation (and block (remember to open mutex!) or not). possible because other threads always grabs the lock, but can be • Still busy wait, but only for a short time lucky…): No Bounded Waiting ( a MUTEX criteria) • Use yield() inside the while loop on uniprocessors • No fairness, no order, random who gets access • Works with multiprocessors 05.09.03 University of Oslo, INF3150 19 05.09.03 University of Oslo, INF3150 20
Recommend
More recommend