CS140 Project Session Notes #1: Threads Haobo Xu, TA Fall Based on Ben Sapp’s slides Download these slides from
Overview ● Getting Started ● Alarm Clock ● Priority Scheduling ● Advanced Scheduler (MLFQS) Ask questions anytime
Getting Started ● Make sure Pintos is up and running – set path = (/usr/class/cs140/`uname -m`/bin $path) – zcat /usr/class/cs140/pintos/pintos.tar.gz | tar x – cd pintos/src/threads/ – make – cd build/ – pintos run alarm-multiple ● Do this on either the Solaris (elaine) or Linux (vine) machines in Sweet Hall
Thread System Overview 4 kB | kernel stack | | | | | V | | grows downward | | | | magic | | : | | status | | tid | 0 kB scheduler timer ready list wait list for keyboard... wait list for hard drive... wait list for some lock... cpu...
Alarm Clock ● reimplement timer_sleep() in devices/timer.c to avoid busy waiting: ● instead, take thread off the ready list /* Suspends execution for approximately TICKS timer ticks. */ void timer_sleep (int64_t ticks){ int64_t start = timer_ticks (); ASSERT (intr_get_level () == INTR_ON); while (timer_elapsed (start) < ticks) thread_yield (); }
Priority Scheduling ● Implement: (a)If a thread is added to the ready list which has a higher priority than the currently running thread, immediately yield the processor to the new thread. (b)Also, when threads are waiting for a lock, semaphore, or condition variable, the highest priority waiting thread should be woken up first. ● How? (a) Check priority whenever adding to the ready list (as in thread_create() ) and choosing next thread to run ( next_thread_to_run()). (b) Each sema, lock, etc. keeps track of the threads that are associated with it...need to check their priority when the lock is released.
Priority Inversion Problem ● But there's a problem – Let's say a high priority thread H needs a lock held by a low priority thread L – H must wait until L runs so L can release its lock. – But L must defer to all higher priorities, so it must wait its turn to run. – In turn, H must wait for all lower priority threads to run before it can run again. – This is bad. H should run first.
Priority Donation Solution ● When a high priority thread waits on a lock held by a lower priority thread, donate the priority level of the high level thread to the low level thread. – Be sure to handle multiple donations, in which multiple priorities are donated to a single thread – Be sure to handle nested donations, e.g., H waits on M which waits on L...
Advanced Scheduler: Multi-Level Feedback Queue ● 64 ready queues, one for each priority ● scheduler chooses a thread from the highest-priority non-empty queue ● priority calculated using the cpu time used by a thread, and it's “niceness”: – priority = PRI_MAX - recent_cpu/4 - nice*2 ● see manual for formulas to calculate recent_cpu ● need to implement fixed point arithmetic library
Synchronization ● keep in mind that threads can be interrupted by other threads – use locks, semas and condition variables to make important updates to shared data ● but, interrupt handlers can't use locks (why?) – this means that you will have to disable interrupts for shared data used by an interrupt handler, i.e., when accessing thread variables, don't want timer interrupt to interfere.
Random Tips ● gdb/cvs: useful tools for the rest of your life – Check out the Debugging Tools section. – Check out the Development Tools section. ● use available data structures, especially list – helpful functions: insert, splice, pop/push front/back, end, begin, next, prev, size, list_empty, sort, max, min... ● read the manual (many times!) ● read the design document template!
Grading ● 50% automatic tests – no exceptions ● 50% design document – where the real grading happens – data structures, algorithms, synchronization, and rationale – coding standards: don't forget to indent and comment!
it's that easy... code to write: devices/timer.c | threads/fixed-point.h | threads/synch.c | threads/thread.c | threads/thread.h | files changed, 440 insertions(+), 29 deletions(-) questions?