Nachos Project 2 Lecturer: Hao-Hua Chu TA: Chun-Po Wang (Artoo) Date: 2008/10/14

advertisement
Nachos Project 2
Lecturer: Hao-Hua Chu
TA: Chun-Po Wang (Artoo)
Date: 2008/10/14
Material Provided by
Yuan-Hao Chang, Yung-Feng Lu
Project 2
• Implement Thread Scheduling
– Default is FCFS
– Priority scheduling + Round Robin
2
Summary
• Motivation & Objective
• Nachos
– Thread
– Scheduler
– Timesharing (Round-robin)
• Requirement
• Submission
3
Motivation & Objective
• Modern operating systems
should have the ability to
schedule multiple threads.
– Low waiting time, or
– Low turnaround time, or
– Avoid starvation
4
Motivation & Objective (cont.)
• Be familiar with Nachos
– Understand the inner structure
– You’ll need to trace in this project
• Implement priority scheduling
algorithms, combine it with built-in
timer to achieve timesharing
(Round-Robin)
5
Nachos 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).
6
Thread Life Cycle
Thread::Thread()
JUST_CREATED
Note:
Thread::Yield() invoks
Scheduler::FindNextToRun() to
select next thread to run.
Thread::Fork()
Call Scheduler::
ReadyToRun()
READY
Event occurs, call
Scheduler::ReadyToRun()
(Move thread back to the ready queue)
(use a readyList)
Call Scheduler::
Run()
Call Thread::Yield()
RUNNING
BLOCKED
Call Thread::Sleep()
(Put thread to waiting queue)
7
Thread Object
• Thread()
– Constructor: sets the thread as JUST_CREATED status
• Fork()
– Allocate stack, initialize registers.
– Call Scheduler::ReadyToRun() to put the thread into
readyList, and set its status as READY.
• Yield()
– Suspend the calling thread and put it into readyList.
– Call Scheduler::FindNextToRun() to select another
thread from readyList.
– Execute selected thread by Scheduler::Run(), 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.
8
Thread 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.
9
Thread Object (Cont.)
• Fork(VoidFunctionPtr func, int arg)
– Thread creation
• Allocating stack by invoking StackAllocate() function
• Put this thread into ready queue by calling
Scheduler::ReadytoRun()
– Argument func
• The address of a procedure where execution is to begin
when the thread starts executing (The thread’s handler
function)
– Argument arg
• An argument that would be passed to thread handler
function
10
Thread Object (Cont.)
• void Yield()
– Suspend the calling thread and
select a new one for execution
• Find next ready thread by calling
Scheduler::FindNextToRun().
• Put current thread into ready list
(waiting for rescheduling).
• Execute the next ready thread by
invoking Scheduler::Run().
– If no other threads are ready to execute,
continue running the current thread.
11
Thread Object (Cont.)
• void Sleep (bool finishing)
– Suspend the current thread and change its state to
BLOCKED
• Run next ready thread
• Invoke interrupt->Idle() 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 Semaphore::P() in code/threads/synch.cc.
• Semaphore::V() will wake up one of the thread in the
waiting queue (sleeping threads queue).
12
Thread 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.
13
Example: 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.
14
The Flow to Invoke SelfTest()
• In main.cc
– if (strcmp(argv[i], "-K") == 0)
threadTestFlag = TRUE;
– if (threadTestFlag)
kernel->ThreadSelfTest();
// test threads and synchronization
• In Kernel::ThreadSelfTest()
currentThread->SelfTest();
// test thread switching
>./nachos -K
kernel->ThreadSelfTest()
Thread::SelfTest()
Fork(SimpleThread,1)
– In Thread::SelfTest()
Thread *t = new Thread("forked thread");
t->Fork((VoidFunctionPtr) SimpleThread, (void *) 1);
kernel->currentThread->Yield();
SimpleThread(0);
15
Nachos 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
16
Nachos Scheduler
• ReadyToRun()
– Change a thread’s 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
Thread::Finish(), terminate it. (indicated by the
variable toBeDestroyed)
17
Scheduler Object (Cont.)
• Scheduler *Scheduler()
– The scheduler constructor
• Initialize the readyList, which is a List
Object.
• Set thread status as JUST_CREATED.
18
Scheduler Object (Cont.)
• void ReadyToRun(Thread *thread)
– Make a thread as ready
• Set thread status as READY.
• Place it on the ready list.
• Invoked by Thread::Fork(), or
Semaphore::V().
• Note that ReadyToRun() doesn't
actually start running the thread.
19
Scheduler Object (Cont.)
• Thread *FindNextToRun()
– Select a ready thread and return it
• Remove and return the thread at the
front of the ready list
20
Scheduler 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. 21
Timesharing 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 Timer::CallBack(), which resets the
timer and call Alarm::CallBack()
– Alarm::CallBack()
• Call interrupt->YieldOnReturn(), which would
yield current thread in Interrupt::OneTick() after
all interrupts are handled
– “TimerTicks” is defined in
code/machine/stats.h, default is 100
22
Timesharing in Nachos
(Cont.)
• Nachos initialize a Alarm object in
Kernel::Initialize()
• 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)
23
Implementation
• 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
24
Read schedule file
• Make Nachos support “-S”
parameter.
– E.g., > ./nachos -S ParameterFile.txt
– When executing Nachos with “-S”
parameter, invoke our scheduler
testing function:
kernel->currentThread->
schedulingTest(param_file_name)
25
Read schedule file (cont.)
• We do actual works in a new function in class
Thread
(Modify code/threads/thread.cc and thread.h)
void Thread::SchedulingTest(char *ParameterFile) {
<Parse the parameter file to put thread’s name, remaining execution ticks, and priority to
ThreadName[], RemainingExecutionTicks[], and ThreadPriorityp[], respectively.>
…
Thread *t;
for(i=0;i<NumberOfThreadsDefinedInParemeterFile;i++)
{
t = new Thread(ThreadName[i]);
t->setPriority(ThreadPriority[i]);
t->Fork((voidFunctionPtr) threadBody,
(void *) RemainingExecutionTicks[i]);
}
26
kernel->currentThread->Yield(); // Give up CPU in order to run new threads
}
Read schedule file (cont.)
• Sample schedule file:
4
A
B
C
D
–
–
–
–
2
1
3
2
7
3
5
4
4 threads: A,B,C,D
Thread name, priority, remaining ticks
Priority = 1~10, 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. DON’T
give it local variables.
27
Read schedule file (cont.)
• Implement thread body:
– We run a while loop, which loops tick_to_exec times.
This parameter is supplied by
Fork(…, (void*) RemainingExecutionTicks[i])
– Call kernel->interrupt->OneTick() to increase system
execution ticks
– Print thread info, including its name and remaining ticks
void threadBody (int tick_to_exec) {
while(tick_to_exec > 0) {
tick_to_exec--;
kernel->interrupt->OneTick();
printf("%s: remaining = %d\n",
kernel->currentThread->getName(), tick_to_exec);
}
}
28
Priority scheduling
• Add required member variables and methods
to Thread class
(code/threads/thread.cc and thread.h)
– void Thread::setPriority(int p)
• Set new priority p to this thread
– int Thread::getPriority()
• Retrieve current priority
– int priority
• A thread’s priority (private variable)
• Modify constructor to give default priority to
new threads
– Thread::Thread()
• In this project, we set default priority to 10 in order to
avoid these threads’ effects when doing our
scheduling
29
Priority 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)
30
SortedList
• 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.
• SortedList<T>::Insert(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. SortedList<Thread*> 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
31
Round-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
32
Sample scheduling result
• Time slice = 100 ticks
• Schedule file:
4
A
B
C
D
2
1
3
2
7
3
5
4
• Why thread D run
before A?
– Timer interrupts
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!
33
Requirement
• Implement priority scheduling
• Write a 2-page report
– Don’t just paste your code, I’ll 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 can’t 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.
34
Test 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 don’t cheat
35
Submission
•
Two people in one group (Write down the
name and student ID of all members in the
report)
The file you need to send:
•
1.
2.
A report in .pdf or .doc
threads.cc, threads.h, scheduler.cc and
scheduler.h
•
Send your files
tar zcvf os_hw2_bXXXXXXXX_bOOOOOOOO.tar.gz
report.doc exception.cc
–
–
–
Tar your files to an archieve named:
os_hw2_bXXXXXXXX_bOOOOOOOO.tar.gz
E-mail to artoo@csie.ntu.edu.tw with following
title:
[os_hw2] bXXXXXXXX_bOOOOOOOO
Please follow the format carefully or our auto36
reply system will not work
Submission (cont.)
• Deadline: 10/27 24:00
– For the delayed submission, deduct
5 points for each day
• DO NOT COPY!!
Protect your code well!!
37
Download