Title: Nachos Project 2
1Nachos Project 2
- Lecturer Hao-Hua Chu
- TA Chun-Po Wang (Artoo)
- Date 2008/10/14
- Material Provided by Yuan-Hao Chang, Yung-Feng Lu
2Project 2
- Implement Thread Scheduling
- Default is FCFS
- Priority scheduling Round Robin
3Summary
- Motivation Objective
- Nachos
- Thread
- Scheduler
- Timesharing (Round-robin)
- Requirement
- Submission
4Motivation Objective
- Modern operating systems should have the ability
to schedule multiple threads. - Low waiting time, or
- Low turnaround time, or
- Avoid starvation
5Motivation Objective (cont.)
- Be familiar with Nachos
- Understand the inner structure
- Youll need to trace in this project
- Implement priority scheduling algorithms, combine
it with built-in timer to achieve timesharing
(Round-Robin)
6Nachos Threads
- Ready queue
- A List object a list of ready thread objects
- Thread state
- READY
- The thread will be kept in readyList.
- RUNNING
- The global variable currentThread always points
the currently running thread. - BLOCKED
- The thread is blocked to wait for some event
until the event takes place. - A blocked thread is not in readyList. Instead, it
would be put in other queues. - JUST_CREATED
- The thread is just created, but not ready to be
put in readyList (not ready to run).
7Thread Life Cycle
ThreadThread()
Note ThreadYield() invoks SchedulerFindNext
ToRun() to select next thread to run.
ThreadFork()
Call SchedulerReadyToRun()
Event occurs, call SchedulerReadyToRun() (Move
thread back to the ready queue)
Call SchedulerRun()
Call ThreadYield()
Call ThreadSleep() (Put thread to waiting
queue)
8Thread Object
- Thread()
- Constructor sets the thread as JUST_CREATED
status - Fork()
- Allocate stack, initialize registers.
- Call SchedulerReadyToRun() to put the thread
into readyList, and set its status as READY. - Yield()
- Suspend the calling thread and put it into
readyList. - Call SchedulerFindNextToRun() to select another
thread from readyList. - Execute selected thread by SchedulerRun(),
which sets its status as RUNNING and call
SWITCH() (in code/threads/switch.s) to exchange
the running thread. - Sleep()
- Suspend the current thread and find other thread
to run - Change its state to BLOCKED.
9Thread Object (Cont.)
- Thread Thread(char debugName)
- The Thread constructor
- Setting status to JUST_CREATED,
- Initializing stack to NULL, and
- Given the thread name for debugging.
10Thread Object (Cont.)
- Fork(VoidFunctionPtr func, int arg)
- Thread creation
- Allocating stack by invoking StackAllocate()
function - Put this thread into ready queue by calling
SchedulerReadytoRun() - Argument func
- The address of a procedure where execution is to
begin when the thread starts executing (The
threads handler function) - Argument arg
- An argument that would be passed to thread
handler function
11Thread Object (Cont.)
- void Yield()
- Suspend the calling thread and select a new one
for execution - Find next ready thread by calling
SchedulerFindNextToRun(). - Put current thread into ready list (waiting for
rescheduling). - Execute the next ready thread by invoking
SchedulerRun(). - If no other threads are ready to execute,
continue running the current thread.
12Thread Object (Cont.)
- void Sleep (bool finishing)
- Suspend the current thread and change its state
to BLOCKED - Run next ready thread
- Invoke interrupt-gtIdle() to wait for the next
interrupt when readyList is empty - Sleep is called when the current thread needs to
be blocked until some future event takes place. - Eg. Waiting for a disk read interrupt
- It is called by SemaphoreP() in
code/threads/synch.cc. - SemaphoreV() will wake up one of the thread in
the waiting queue (sleeping threads queue).
13Thread Object (Cont..)
- void Finish()
- Terminate the currently running thread.
- Call Sleep() and never wake up
- De-allocate the data structures of a terminated
thread - The newly scheduled thread examines the
toBeDestroyed variable and finish this thread.
14Example create thread
- void SelfTest()
- Test whether thread implementation works.
- Fork a new thread and yield current one to
execute it - static void SimpleThread(int which)
- A procedure where execution is to begin when the
thread starts executing - Command line nachos -K
- In this project, you can trace the above two
functions as the starting point.
15The Flow to Invoke SelfTest()
- In main.cc
- if (strcmp(argvi, "-K") 0) threadTestFlag
TRUE - if (threadTestFlag) kernel-gtThreadSelfTest()
// test threads and synchronization - In KernelThreadSelfTest()currentThread-gtSelfTes
t() // test thread switching - In ThreadSelfTest()Thread t new
Thread("forked thread")t-gtFork((VoidFunctionPtr)
SimpleThread, (void ) 1)kernel-gtcurrentThread-
gtYield()SimpleThread(0)
gt./nachos -K
kernel-gtThreadSelfTest()
ThreadSelfTest()
Fork(SimpleThread,1)
16Nachos Scheduler
- In code/threads/scheduler.cc, shceduler.h
- Decides which thread to run next.
- Invoked whenever current thread wishes to give up
the CPU. (Eg. Call Yield()) - Default scheduling policy A FCFS readyList with
round-robin fashion - RR is supported by Timer object, which generate
interrupt every 100 ticks
17Nachos Scheduler
- ReadyToRun()
- Change a threads status to READY and put it into
the readyList. - FindNextToRun()
- Fetch the thread at the front of the readyList.
- Run()
- Change the state of a thread to RUNNING.
- Invoke SWITCH() to switch from the current thread
to the selected thread. - If we switch threads because current thread
called ThreadFinish(), terminate it. (indicated
by the variable toBeDestroyed)
18Scheduler Object (Cont.)
- Scheduler Scheduler()
- The scheduler constructor
- Initialize the readyList, which is a List Object.
- Set thread status as JUST_CREATED.
19Scheduler Object (Cont.)
- void ReadyToRun(Thread thread)
- Make a thread as ready
- Set thread status as READY.
- Place it on the ready list.
- Invoked by ThreadFork(), or SemaphoreV().
- Note that ReadyToRun() doesn't actually start
running the thread.
20Scheduler Object (Cont.)
- Thread FindNextToRun()
- Select a ready thread and return it
- Remove and return the thread at the front of the
ready list
21Scheduler Object (Cont.)
- void Run(Thread nextThread)
- Suspend the current thread and switch to the new
one. - Set it as toBeDestroyed if it is a finished
thread. - Save the state of the old thread.
- Switch to the next thread by invoking SWITCH and
set it as running. - SWITCH is defined in code/threads/switch.s
- CheckToBeDestroyed() -- check if the previous
thread need to be clean up.
22Timesharing in Nachos
- Alarm object
- code/threads/alarm.cc and alarm.h
- Nachos create a Timer object which interrupts
every TimerTicks ticks - code/machine/timer.cc and timer.h
- When Timer interrupts, nachos calls its interrupt
handler TimerCallBack(), which resets the timer
and call AlarmCallBack() - AlarmCallBack()
- Call interrupt-gtYieldOnReturn(), which would
yield current thread in InterruptOneTick()
after all interrupts are handled - TimerTicks is defined in code/machine/stats.h,
default is 100
23Timesharing in Nachos (Cont.)
- Nachos initialize a Alarm object in
KernelInitialize() - Alarm generates interrupts every 100 ticks
(default) - Nachos yields current thread in Alarm interrupt
handler - In effect, no thread could run longer than 100
ticks (unless there is no other threads)
24Implementation
- We have 3 tasks
- Extend Nachos to read our schedule file and
create threads - Implement a priority scheduling to replace
default FCFS - Round-Robin mechanism is already built by Alarm
object, but we can change its time slice - The function names with bold font should be
implemented by you
25Read schedule file
- Make Nachos support -S parameter.
- E.g., gt ./nachos -S ParameterFile.txt
- When executing Nachos with -S parameter, invoke
our scheduler testing function
kernel-gtcurrentThread-gt schedulingTest(param_file
_name)
26Read schedule file (cont.)
- We do actual works in a new function in class
Thread (Modify code/threads/thread.cc and
thread.h)
void ThreadSchedulingTest(char ParameterFile)
ltParse the parameter file to put threads
name, remaining execution ticks, and priority to
ThreadName, RemainingExecutionTicks, and
ThreadPriorityp, respectively.gt Thread
t for(i0iltNumberOfThreadsDefinedInPareme
terFilei) t new Thread(ThreadNamei)
t-gtsetPriority(ThreadPriorityi) t-gtFork(
(voidFunctionPtr) threadBody, (void )
RemainingExecutionTicksi) kernel-gtcurrentTh
read-gtYield() // Give up CPU in order to run new
threads
27Read schedule file (cont.)
- Sample schedule file
- 4
- A 2 7
- B 1 3
- C 3 5
- D 2 4
- 4 threads A,B,C,D
- Thread name, priority, remaining ticks
- Priority 110, 1 is the highest priority
- Thread name is 10 characters (including NULL) or
less, NOTE THAT you should provide a newly
allocated space for name strings to Thread
constructor because it only stores pointer. DONT
give it local variables.
28Read schedule file (cont.)
- Implement thread body
- We run a while loop, which loops tick_to_exec
times.This parameter is supplied by Fork(,
(void) RemainingExecutionTicksi) - Call kernel-gtinterrupt-gtOneTick() to increase
system execution ticks - Print thread info, including its name and
remaining ticks
void threadBody (int tick_to_exec)
while(tick_to_exec gt 0) tick_to_exec-- ker
nel-gtinterrupt-gtOneTick() printf("s remaining
d\n", kernel-gtcurrentThread-gtgetName(),
tick_to_exec)
29Priority scheduling
- Add required member variables and methods to
Thread class (code/threads/thread.cc and
thread.h) - void ThreadsetPriority(int p)
- Set new priority p to this thread
- int ThreadgetPriority()
- Retrieve current priority
- int priority
- A threads priority (private variable)
- Modify constructor to give default priority to
new threads - ThreadThread()
- In this project, we set default priority to 10 in
order to avoid these threads effects when doing
our scheduling
30Priority scheduling (cont.)
- Modify Scheduler class
- code/threads/scheduler.cc and scheduler.h
- How to do? Please figure it out yourself
- You may need to use SortedList class
- If two threads have the same priority, the first
thread in the schedule file runs first (FCFS)
31SortedList
- SortedList inherits List class, except that it
can insert an item into a list in
increasing/decreasing order. - When creating a new SortedList object, we have to
register a compare function, which decides
which element is bigger. - SortedListltTgtInsert(T item)
- Insert an item into a list by invoking the
registered compare function to decide the place
to put the item in the list. - This is a template class, which can be used on
different data types - Eg. SortedListltThreadgt is a SortedList class
which stores pointers to Thread objects - The SortedList uses the compare function you
implemented to determine which Thread object is
bigger, or have higher priority
32Round-Robin
- Alarm class generates interrupts every TimerTicks
ticks (default 100) - TimerTicks is defined in code/machine/stats.h
- You can change it, and watch the differences
33Sample scheduling result
B remaining 2 B remaining 1 B remaining
0 D remaining 3 D remaining 2 D remaining
1 D remaining 0 A remaining 6 A
remaining 5 A remaining 4 C remaining
4 C remaining 3 C remaining 2 C remaining
1 C remaining 0 A remaining 3 A
remaining 2 A remaining 1 A remaining
0 Machine halting!
- Time slice 100 ticks
- Schedule file
- 4
- A 2 7
- B 1 3
- C 3 5
- D 2 4
- Why thread D run before A?
- Timer interrupts
34Requirement
- Implement priority scheduling
- Write a 2-page report
- Dont just paste your code, Ill read it myself
- Change time slice to 50 ticks, run nachos on test
schedule we supply and explain the results - You may need to use -d to trace the execution
- If your project submission cant compile and
execute on Linux in Workstation Room 217, we will
consider it as fail. - Please contact me to apply a workstation account
if you need it.
35Test files
- We supply a test schedule file testThreads.txt
on our webpage - Your implementation should have the same results
as the sample scheduling when time slice 100 - We will use other schedules to test, so dont
cheat
36Submission
- Two people in one group (Write down the name and
student ID of all members in the report) - The file you need to send
- A report in .pdf or .doc
- threads.cc, threads.h, scheduler.cc and
scheduler.h - Send your files
- Tar your files to an archieve namedos_hw2_bXXXXX
XXX_bOOOOOOOO.tar.gz - E-mail to artoo_at_csie.ntu.edu.tw with following
titleos_hw2 bXXXXXXXX_bOOOOOOOO - Please follow the format carefully or our
auto-reply system will not work
tar zcvf os_hw2_bXXXXXXXX_bOOOOOOOO.tar.gz
report.doc exception.cc
37Submission (cont.)
- Deadline 10/27 2400
- For the delayed submission, deduct 5 points for
each day - DO NOT COPY!!Protect your code well!!