Nachos Project #1
Due Wednesday 15 April 1998
Setup & Project Technique, Context Switch
Copyright information
Last modified: Sun Apr 12 11:27:46 CDT
Project #1 is due on Wednesday, 15 April, at 7:30 AM. The due time is
chosen to encourage you to be done many hours before it. This is not
the sort of thing to try to finish up at the last minute. I will be
extremely busy with a conference 9-11 April, and out of town 12-14
April, so make sure that you bring problems to me before the 9th.
Basic goals
The real goals
In this introductory project, you will familiarize yourself
with lab technique and tools for the more substantial later steps. You
will use
- XWindows for a windowed interface to your work,
- emacs, xemacs, vi, or other windowed
editor to manipulate code and documentation,
- tcsh or another UNIX shell to issue commands,
- gmake to compile project code, and
- RCS to track changes to code.
You will also discover the rather subtle way that the thread
scheduling and context switching work in Nachos. The steps in
project #1 are small, and have nothing specially to do with making an
operating system work. But, it is very important to be fluent in the
silly little things so that they don't distract you from the real work
later. Unless you have previous experience with systems programming,
you will probably spend a lot of time on this assignment.
The postulated goals
The real point of this project is to practice for the real
thing. But, for the sake of that practice, we'll postulate the
following goals.
- Compile the entire Nachos code. (You will probably not
achieve quite all of this, as described in Step 3 below.)
- Test the basic features of Nachos (Step 4 below).
- Modify the Nachos thread scheduler to provide more debug
output (Step 5 below).
- Demonstrate and describe a mysterious behavior of the thread
scheduler, uncovered by your new output.
- Work out the flow of control in thread scheduling and context
switching with further debug output and a carefully crafted test
run.
- Com Sci 330 only: Discover,
demonstrate, and correct a minor bug in Nachos that leads to a
space leak.
The program code that you need to write is very tiny. Nonetheless,
this initial project can be a lot of work. The good news is that it
will prepare you for the later, conceptually more substantial,
assignments.
Step 1: Set up your work environment
- Get
yourself a CS department instructional UNIX account.
- Choose an agreeable place to work, where you can reach
classes.cs.uchicago.edu from a workstation running
XWindows. You may use the SGI machines in the Ryerson 175
labs with your CS accounts.
- Open a Web browser, and use it to read these instructions as you
do the project.
- Open a window with a UNIX shell on
classes.cs.uchicago.edu. Use ssh to connect if at
all possible: it has both speed and security
advantages (type man ssh to find out more). If ssh
is not available where you work, fall back on rlogin,
rsh, or telnet.
- Get comfortable with shell interaction. If you need help, get the
very short book
Learning
the UNIX Operating System and use it as a tutorial.
- Open a window with a good text editor operating on the
classes file system. I prefer xemacs or
emacs, but some swear by vi. The SGIs in Ryerson
175 are on the same file system as classes, so you
can just run your favorite editor directly on these machines. If you
are using an X workstation somewhere else, learn how to set
the DISPLAY variable, so that an editor running on
classes will display on your workstation. If remote
X is too slow, these editors will also run in a login
window. But, use two different windows for shell interaction and
editing in any case.
- Execute man command and/or info for
any command that you don't understand.
There are lots of different ways to customize your work environment to
suit your own taste. Talk to your friends, and experiment.
Step 2: Set up your Nachos code directory
- Create your own Nachos code directory on classes.
Call it ~/CS230/Nachos/code.
- Make your own personal copy of the entire Nachos source
code. Take it from
/usr/local/classes/current/CS230/01/Nachos/nachos-3.4/code, using
cp -r.
- Give the command chmod -R u+w code to make your personal
code writable.
- In your own code directory, give the command
chmod go-rx. This will make your personal code directory a
private place, readable only by you.
Step 3: Compile Nachos
- Go to your code directory, and execute gmake
clean. This deletes everything except source code, so you are
sure to start with executables that match the source. The code is
already clean, so you'll get an error message saying ``no
match.'' That's OK.
- Execute gmake -n | less, to see what operations
gmake intends to do, without actually doing them. You
won't get much out of the output this time, but it's a good habit
to start. There will be error messages at the end, but go ahead
anyway.
- Execute gmake >& gmlog1 &. This may take a
few minutes, depending on the load. You can look at the output
in gmlog1 at leisure. To check the progress, execute
tail -f gmlog1.
You will see a lot of compiler
warnings. That's OK. The gmake will fail in the
test directory. Fortunately, we don't need that part for a
few weeks, so I have time to fix it. Whenever you change your
Nachos code, you will run gmake again to
automatically recompile only those items affected by your
change.
Step 4: Run Nachos
- In your code directory, execute ls -l
*/nachos. You should see five different executable versions of
nachos in five subdirectories. Run them. All of them should
produce some short diagnostic output, except for network/nachos,
which will hang until you kill it. Your real project work will
involve changing Nachos code, recompiling these executable
nachos commands, and demonstrating their behavior.
- Execute nachos -rs 47. The -rs option simulates
pseudorandom interrupts, using the number that you provide as a
seed. This is great for debugging, since the same random seed will
produce the same interrupts. Try different seeds of your own
choice. The impact of interrupts is not very exciting at this stage:
no impact on some of the nachos versions, and a change in the
number of ticks reported for others. It will get more interesting
later.
- Execute nachos -d and observe the extra debugging
information. Try threads/nachos -d | grep Yield.
- Check the Nachos documentation, and exercise any other
interesting features that you notice.
Step 5: Modify Nachos
Now, you will modify threads/scheduler.cc to print more
diagnostic information.
- Go to your code/threads directory, and check in
scheduler.cc with RCS before you change it. Usually, you will
need to do mkdir RCS, but I already did that because I had to
fix Nachos for the Solaris system. Do ls -l
RCS and you'll see that I already checked in Makefile
and two other files. Do ci -l scheduler.cc. ci will
prompt you for a comment. You can safely skip this comment (type a
period followed by return), since it is just a general description of
the file. Then, do ls -l RCS again to see that you have
checked in scheduler.cc.
- Open scheduler.cc in your editor. Find a call to
SWITCH(oldThread, nextThread), followed by a DEBUG
command printing out currentThread. Add a pair of comments
just after this DEBUG command, of the form
// New from your name
// End your name
Throughout the project, mark every change that you
make to a Nachos with similar marks (or ``Modified by
your name'' if you change old code instead of adding new
code). This is important for your lab technique, and also I will only
evaluate the work that you mark in this way.
- Make two copies of the DEBUG command inside your
marks. Modify them to print out oldThread and
nextThread, with appropriate identifying text. Usually, you
will add a comment describing the impact of such a change, but in this
case the DEBUG commands are self-documenting.
- Execute gmake again in your code directory. Find
the line in its output indicating that threads/scheduler and
threads/nachos were recompiled. Go back to
code/threads and do ls -l, noticing what has and
hasn't changed.
- Run threads/nachos with and without the -d
option. Look at the diagnostic output from your new DEBUG
commands. You should be puzzled. They are not what the
C source code in scheduler.cc suggests.
- When you have succeeded in compiling and testing your change, go
to code/threads and do ci -l scheduler.cc
again. This time, type in a comment, such as, ``Added debug output of
oldThread and nextThread after the context switch.'' It is
very important to form a habit of checking in with
RCS after every small change.
- Try out rlog scheduler.cc and rcsdiff
scheduler.cc with various options to see what sort of information
RCS offers you. My recommended form of check-in, ci -l, checks
the file out again. If you goof up the check-in, you will need to
learn about the check-out command, co. If you goof up the
code files, and need to unwind from an error, you will need to read
the manual pages for RCS, ci, and co very
carefully.
- Add more DEBUG commands in strategic places to illuminate
the flow of control in context switching. Use the character flag
`c' (for context switch to enable these new
DEBUG commands. Don't modify switch.s, but trace
back from the call to SWITCH in scheduler.cc. Look
at my
guide
to reading the Nachos source for help. You should
definitely add DEBUG commands to scheduler.cc and
to thread.cc.
- Create a new test program to display the context switch more
efficiently than threadtest.cc does. In this case, do not
modify threadtest.cc. Instead, copy threadtest.cc to
a new file, such as switchtracetest.cc, and modify the new
file to suit. When you first check in the new file to RCS,
provide a comment of the form ``Initialized from
threadtest.cc.'' Give the functions in your new files new
names, of course.
- Run gmake again, just to be sure that your new material
compiles. By now, you are probably tired of watching the voluminous
output from gmake in your code directory. The
Makefiles in Nachos are organized so that you can
make a single directory by executing gmake in that directory
(don't assume that this works for all code distributions). But, you
need to set things up for switchtracetest.cc, and the right
way is a bit delicate. code/threads/Makefile is generated
automatically, and you should not change it. Rather, look at
code/Makefile.common. Notice how threadtest.cc and
threadtest.o are mentioned there. Add
switchtracetest.cc and switchtracetest.o in
analogous form (of course, you checked in
code/Makefile.common with RCS first). Execute
gmake depend in code/threads to update
code/threads/Makefile, and then execute gmake to
compile your new code. Whew.
- Run nachos again. Nothing changed, because your new test
program didn't get invoked.
- Look at threads/main.cc, and notice the call to the
function ThreadTest(). You need to change main.cc to
call your new function (I called mine TraceSwitch). But, you
want to do this without losing the old possibilities of
ThreadTest. Notice the conditional compilation of the call to
ThreadTest:
#ifdef THREADS
ThreadTest();
#endif
Run grep THREADS Make* to find out where THREADS is
defined. Look at the output from gmake, and notice how the
definition of THREADS gets into the command that compiles
main.cc. You need to do something similar to choose between
ThreadTest and TraceSwitch. I chose a variable
called SWITCHTRACE, and created the following nested
conditional:
#ifdef THREADS
#ifdef SWITCHTRACE
TraceSwitch();
#else
ThreadTest();
#endif
#endif
We are still essentially concerned with threads, so we don't want to
disable THREADS, in case some other code depends on it (now
or in the future). Our final problem is to define SWITCHTRACE
for next compile. Look again at the way SWITCHTRACE is
defined in the Makefile. It's best not to change the
Makefile itself, but we can override variable settings when
running gmake. gmake DEFINES="-DTHREADS
-DSWITCHTRACE" will do it.
- Well, gmake DEFINES="-DTHREADS -DSWITCHTRACE" probably
had no impact, because a mere change in command-line parameters
doesn't trigger recompilation. The -W option to
gmake is supposed to deal with this problem, but it doesn't
appear to work. So, do touch main.cc to mark main.cc
as recently changed, and then do your gmake.
The method above for incorporating a minor change to main.cc
probably looks ridiculously convoluted. There is probably a somewhat
more elegant method (in particular, we shouldn't have to repeat the
definition of THREADS when adding SWITCHTRACE on the
command line), and I hope someone will find it and post it. But, the
lazy methods, such as just typing the right compiler command directly,
are a big mistake for the long run. All that work was not really to
make the tiny change to the nachos command. Rather, it was to
record the information about a new variation on the nachos
command in a form that will interact nicely with other changes that we
decide to make later. That is an inherently delicate problem, and
that's what the code management problem is all about.
Com Sci 330 only: find and fix the ``undead thread'' problem
By a combination of studying the Nachos code, reading my
guide to the code, and running interesting test cases with
enlightening debug output, understand the somewhat subtle way in which
Nachos removes a thread that has Finished. Discover
and demonstrate a subtle bug that sometimes leaves a Finished
thread forever in an ``undead'' state (a similar problem happens in
UNIX sometimes). The problem occurs when one thread tries to
Finish, the next thread is brand new and it Finishes
in its first period of execution. Explain the consequences of this bug
(they are not usually disastrous, but they can be modestly
harmful). Correct the bug, by replicating a small bit of code that
needs to appear twice, but only appears once. Demonstrate the behavior
of your correcton.
My guide to Nachos code discusses this problem in some
detail.
Step 6: Demonstrate your work
Although most people find this counterintuitive, merely getting a
computer program to work is less important than demonstrating its
behavior to other people. A large part of my evaluation of your
project work will depend on your demonstrations. I may occasionally
provide test data for input, but designing your own tests is a crucial
part of each project assignment. For this preliminary assignment,
there isn't much to demonstrate, but we'll go through the motions
anyway, to practice for the real thing.
- In your code directory, create a subdirectory named
Project_1_tests. Put in this directory all supporting
materials for your demonstration, particularly files of test input
(file-name.in) and the corresponding output
(file-name.out).
- In your code directory, create a file named
project_1_notes.txt. This is the first file that I will look
at, and I will expect it to lead me to all other interesting
material.
- In project_1_notes.txt provide the following 3-4 sections:
- A brief statement of the project goals, and what you achieved.
- A brief explanation of the changes and additions that you made
to Nachos code. This section must contain explicit references
to the files that you changed and added. List the changed and
added files in an index at the end of the section.
- A demonstration of what you accomplished. This section must
contain precise instructions that will lead me through the
demonstration. Prepare sample inputs in separate files. Provide in
this section the commands that I can execute to observe the
demonstration. I will execute the commands by cutting and pasting
directly from your instructions. After each command that I should
execute, describe briefly what we learn from the output.
- Optional discussion of your conclusions and observations.
Designing good demonstration inputs is one of the hardest and most
important parts of project work. This introductory project is too
trivial to provide much practice in that line, but please start
thinking about the problem for future project work. Voluminous inputs
are not usually helpful. Rather, you need test cases that I
can read, which will lead me very efficiently to understand your
code. Think of the demonstration inputs as supplements to code
reading, not as stand-alone tests.
Step 7: Submit your work
Revised on Sunday 12 April
When you have a coherent, documented version of your project work,
run the command
/usr/local/classes/current/CS230/01/bin/submit-project Project_1.
This command copies your work to a directory where I can evaluate
it. You may resubmit as often as you like before 7:30 AM on Wednesday
15 April. Each new submission will wipe out the previous one, and I
will only evaluate the last one. I suggest that you submit well
organized, but incomplete, results several times along the way. With
this strategy, you can reduce last-minute panic, since you'll only be
risking the latest improvements, and not all of the early
work. But, please do not submit work without the required
internal documentation and explanation. That is, submit work that is
incomplete in project functionality, but not work that is incomplete
in organization.
Soren Dayton (csdayton@cs) created the
submit-project command, and he needs to install it in the
directory that I mentioned. He will post final instructions when the
installation is done. Contact him by e-mail with minor problems. If
there are serious problems with the procedure, I will deal with them
on Wednesday, and will not penalize anyone for lateness due to the
submission procedures.