Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
COS 318: Operating Systems Implementing Threads Jaswinder Pal Singh Computer Science Department Princeton University (http://www.cs.princeton.edu/courses/cos318/) Today’s Topics u Non-preemptive versus preemptive threads u Kernel vs. user threads u Too many cookies problem 2 Revisit Monolithic OS Structure u u Kernel has its address space, shared with all processes Kernel consists of l l l l l u Boot loader BIOS Key drivers Threads Scheduler User Process User Process Scheduler l l l Use a ready queue to hold all ready threads Schedule in a thread with the same address space (thread context switch) Schedule in a thread with a different address space (process context switch) Kernel scheduler 3 Non-Preemptive Scheduling Terminate (call scheduler) Scheduler dispatch Running Block for resource (call scheduler) Yield (call scheduler) Create Exited Ready Blocked Resource becomes available (move to ready queue) 4 Scheduler u A non-preemptive scheduler invoked by calling l l block() yield() u The simplest form Scheduler: save current process/thread state choose next process/thread to run dispatch (load PCB/TCB and jump to it) u Scheduler can be viewed as just another kernel thread 5 Where and How to Save Thread Context? u Save the context on the thread’s stack l l Many processors have a special instruction to do it efficiently But, need to deal with the overflow problem Thread 2 Thread 1 u frame frame frame frame Save the context of Thread 1 to its stack frame frame Context frame frame Check before saving l l l Make sure that the stack has no overflow problem Copy it to the TCB residing in the kernel heap Not so efficient, but no overflow problems 6 Preemption u Why l l u CPU Interrupts l l u Timer interrupt for CPU management Asynchronous I/O completion Between instructions Within an instruction, except atomic ones Memory Interrupt Manipulate interrupts l l l Disable (mask) interrupts Enable interrupts Non-Masking Interrupts 7 State Transition for Non-Preemptive Scheduling Terminate (call scheduler) Scheduler dispatch Running Block for resource (call scheduler) Yield (call scheduler) Create Exited Ready Blocked Resource becomes available (move to ready queue) 8 State Transition for Preemptive Scheduling Terminate (call scheduler) Scheduler dispatch Create Ready Running Exited Block for resource (call scheduler) Yield, Interrupt (call scheduler) Blocked Resource free, I/O completion interrupt (move to ready queue) 9 Interrupt Handling for Preemptive Scheduling u Timer interrupt handler: l l u I/O interrupt handler: l l l u Save the current process / thread to its PCB / TCB Call scheduler Save the current process / thread to its PCB / TCB Do the I/O job Call scheduler Issues l l Disable/enable interrupts Make sure that it works on multiprocessors 10 Dealing with Preemptive Scheduling u Problem l u An obvious approach l u Interrupts can happen anywhere Worry about interrupts and preemptions all the time What we want l l l l Worry less of the time Low-level behavior encapsulated in “primitives” Synchronization primitives worry about preemption OS and applications use synchronization primitives Concurrent applications OS services Synchronization primitives Scheduling and interrupt handling 11 User Threads vs. Kernel Threads User Process User Process User Process Scheduler u u u Context switch at user-level without a system call (Java threads) Is it possible to do preemptive scheduling? What about I/O events? Kernel scheduler u A user thread l l u Makes a system call (e.g. I/O) Gets interrupted Context switch in the kernel 12 Summary of User vs. Kernel Threads u User-level threads l l l l l u Kernel-threads l l u User-level thread package implements thread context switches OS doesn’t know the process has multiple threads Timer interrupt (signal facility) can introduce preemption When a user-level thread is blocked on an I/O event, the whole process is blocked Allows user-level code to build custom schedulers Kernel-level threads are scheduled by a kernel scheduler A context switch of kernel-threads is more expensive than user threads due to crossing protection boundaries Hybrid l It is possible to have a hybrid scheduler, but it is complex 13 Interactions between User and Kernel Threads u Two approaches l l Each user thread has its own kernel stack All threads of a process share the same kernel stack Private kernel stack Shared kernel stack Memory usage More Less System services Concurrent access Serial access Multiprocessor Yes Not within a process Complexity More Less 14 “Too Many Cookies” Problem u u Want cookies, but don’t want to buy too many cookies Any person can be distracted at any point RoomMate A RoomMate B 15:00 Look in cabinet: out of cookies 15:05 Leave for Wawa 15:10 Arrive at Wawa Look at fridge: out of cookies 15:15 Buy a bag of cookies Leave for Wawa 15:20 Arrive home; put cookies away Arrive at Wawa 15:25 Buy a bag of cookies Arrive home; put cookies away Oh No! Too many cookies. 15 Using A Note? Thread A Thread B if (noCookies) { if (noNote) { leave note; buy cookies; remove note; } } if (noCookies) { if (noNote) { leave note; buy cookies; remove note; } } u Any issue with this approach? 16 Another Possible Solution? Thread A Thread B leave noteA if (noNoteB) { if (noCookies) { buy cookies } } remove noteA leave noteB if (noNoteA) { if (noCookies) { buy cookies } } remove noteB Didn’t buy cookies u Does this method work? Didn’t buy cookies 17 Yet Another Possible Solution? Thread A Thread B leave noteA while (noteB) do nothing; if (noCookies) buy cookies; remove noteA leave noteB if (noNoteA) { if (noCookies) { buy cookies } } remove noteB u Would this fix the problem? 18 Remarks u The last solution works, but l l l u Life is too complicated A’s code is different from B’s Busy waiting is a waste What we want is: Acquire(lock); if (noCookies) buy cookies; Release(lock); Critical section 19 What Is A Good Solution Only one process/thread inside a critical section u No assumption about CPU speeds u A process/thread inside a critical section should not be blocked by any process outside the critical section u No one waits forever u Works for multiprocessors u Same code for all processes/threads u 20 Summary u Non-preemptive threads issues l l u Preemptive threads l u Interrupts can happen any where! Kernel vs. user threads l u Scheduler Where to save contexts Main difference is which scheduler to use Too many cookies problem l What we want is mutual exclusion 21