In this assignment you will be implementing two alternative scheduling algorithms for OS/161: nonpreemptive random scheduling and the multilevel feedback scheduling algorithm described in class.
Recall that you must have your path correctly set to
undertake all CS 134 assignments. If you haven't done so already, put
the appropriate line in your .login
,
.bashrc
, or .zshrc
.
You no longer need your code from Assignment 3. You may delete your
entire source tree (although you may wish to save your patch and any
other changes for posterity). Do not use svn rm
to
remove old code; simply blow it away with plain rm
.
That way, your code can be recovered later if needed (most notably,
for grading).
For this assignment, check out and setup
your
hw4
directory in the usual way, then configure and build
the kernel using the SCHED
configuration files, named
SCHED-RR
, SCHED-MLF
, and
SCHED-RAND
(see previous assignments for details).
Note that a single instance of the OS/161 sources can support multiple
configurations and builds. For this homework, you will have build
areas named SCHED-RR
, SCHED-MLF
, and
SCHED-RAND
in src/kern/compile
. Each
build directory is independent.
You should have already read enough of OS/161 to understand how the
thread system and scheduler work at a basic level. You should review
sched_rr.c
(formerly scheduler.c
) and
thread.c
to ensure you understand how the existing
round-robin scheduler works. Note that the code now differentiates
involuntary and voluntary context switches, such as those that happen
during I/O wait. To support this change, mi_switch
now
takes an extra argument (SW_VOLUNTARY
or
SW_QUANTEXP
), and the hardclock
function in
hardclock.c
now calls thread_timeryield
instead of thread_yield
.
In addition, you should make sure you understand the winning patch
that provides file and process system calls. This patch has already
been applied to the code. The revised source also includes some other
other small changes, including adding a simple shell (accessible via
the s
command at the kernel prompt) and adding a
yield
system call to allow a process to voluntarily give
up its time slice.
Note: whenever you run the shell, it will complain about "Unknown syscall 28". You can ignore that error.
The most fundamental requirement is that your code be simple and easy to follow. You may not use any clever data structures (such as a priority queue) to represent the queue of ready processes. You must use an array (as in the provided code) and use a simple linear search—the array is usually going to be short enough that any inefficiency shouldn't matter too much.
Your multilevel feedback (MLF) scheduler (whose main implementation
code you will put in sched_mlf.c
) should behave
according to the description given on the
Example “Real” Scheduler
page. You may add code that should only be compiled in when the MLF
scheduler is used by bracketing this MLF-specific code as follows:
#include "opt-mlfsched.h" ... #ifdef OPT_MLFSCHED ... (MLF-specific code) #endif /* OPT_MLFSCHED */
The same technique can also be applied to make conditional code for the RR and RAND schedulers.
Your nonpreemptive random scheduler (RAND) scheduler (whose main
implementation code you will put in sched_rand.c
) should
pick a random ready task and run it until the task either completes,
blocks, or voluntarily yields the processor.
You should, however, determine a way to handle processes that are compute-bound and do not complete or voluntarily yield in a reasonable amount of time. It is up to you to decide on a reasonable strategy to handle such tasks—you will need to deal with such unresponsive tasks, but it is up to you to decide on (and justify) the correct way to handle these processes once the kernel has made the determination that they are taking too long.
Most importantly, your implementation should not advantage processes that “break the rules,” and should justifiably fit the description of being a “nonpreemptive random scheduler.”
As usual, once you have final working code, you should create a patch
for OS/161. The patch should be named sched.patch
and
placed in the handin
directory, as usual, along with
documentation sched.txt
. You probably shouldn't create
the patch until after you have completed the performance analysis step
described in the next section.
In this part of the assignment, you will perform a qualitative and quantitative analysis of the performance of all three scheduling algorithms. To compare performance quantitatively, you will need some numerical measures.
You should have noticed that System/161 provides some hardware
performance counters, such as the number of cycles in supervisor mode,
the number of cycles in user mode, and so forth, which it prints when
the kernel exits. These measures, along with the fact that kernel
menu arguments can be given on the sys161
command line,
should allow you to obtain some basic measurements of execution time.
You may find it useful to implement some software counters as well. As a start, we suggest:
You should add the necessary infrastructure to maintain these statistics, as well as any other statistics that you think you will find useful in tuning your schedulers.
Once you have added any instrumentation, it is time to tune your operating system.
Maintain all your data and observations from this section in a file named performance.txt
in the handin
directory.
testbin
to test your scheduler (e.g., add.c
,
hog.c
, farm.c
, sink.c
,
kitchen.c
, ps.c
), or write your own.
performance.txt
. (Your goal should be to improve
on these numbers.)
Although the steps above form a linear sequence, you can use your judgment in developing a testing strategy. In particular, it may help to analyze just one program first, and then choose another that seems like it might have quite different behavior.