P436 / P536: Project Mechanics

Table of Contents

Sharing Files, Part 1: Access Control
Sharing Files, Part 2: Disk Quotas
Copying Nachos
Compiling Nachos
Cross-Compiling User Programs
Running Nachos
Overflow of Call Stacks
Version Management Software
Submitting Assignments

Sharing Files, Part 1: Access Control

Note: For general help with UNIX, see
UNIXHelp for Users.

Members of a team will need to share files with each other. The recommended way to do this is to use Access Control Lists (ACLs), a feature of Solaris. The Detailed Instructions for Copying Nachos contain some comments about setting up ACLs for nachos. For general information on ACLs, see the man pages for setfacl and getfacl. Another useful resource is Rob's Intro to ACLs. Here are a few other tips:

If you have difficulty using ACLs, the best way to get help is to post your questions to the newsgroup cs.system.

For grading purposes, you also need to give user os read permission for your Nachos files, and read and execute permissions for your Nachos directories and all directories on the path from your home directory to your Nachos directories. Be sure to set your ACLs appropriately! We can't give anyone credit for files that we can't read!

A more traditional way to share files under UNIX is by using groups. Our system administrators prefer that you use ACLs to share files, because you can create and delete ACLs yourselves, while groups must be created by the system administrators. If you feel strongly about using UNIX groups to share your files, post to cs.system a request for creation of a group with the appropriate members. You will still need to use ACLs in order to give os access to your Nachos files for grading purposes (unless you include os in your UNIX group).

Sharing Files, Part 2: Disk Quotas

Whether you use ACLs or groups for access control, you will also have to contend with disk quotas.

You need to have a non-zero disk-space quota on any partition of the filesystem in which you want to create files. If you create a file in someone else's directory, you are the owner of the new file, so you need to have a non-zero disk-space quota on the partition containing that user's home directory (otherwise, you will get an error when you try to create the file).

Most people have a non-zero disk-space quota only on the partition containing your home directory. Thus, you and your teammates will probably need to have your home directories on the same partition. Arranging this on the Sharkestra would be difficult, because there are over a dozen partitions. On the burrow, there are only two partitions for home directories, so the syadmin's can easily move your burrow home directories so that they are on the same partition. So, we recommend that all students (even grad students) use their burrow account for the project files.

Note: You can access your burrow home directory directly from the Sharkestra with the pathname /nfs/paca/u/YOURID. You can still run all of your programs on the Sharkestra.

If you and your teammates find that your burrow home directories are not on the same partition, post a message to cs.system stating the names and userid's of everyone on your team and requesting that your burrow home directories be put on the same partition.

There are several ways to find out whether your burrow home directories are on the same partition. For one, you could just set up the file access permissions, then have each team member try to create files in your team's copy of the nachos directory. If you get the error "Disk Quota Exceeded" (or something similar), then you aren't on the same partition. Another method is to cd to your burrow home directory then run the command "df .". The rightmost string (labeled "Mounted on") is the name of the partition.

Copying Nachos

Nachos is installed in ~os/nachos-dfs, which is accessible from both the Burrow and the Sharkestra.
Here are
Detailed Instructions for Copying Nachos.

Most of the programs mentioned below (with exceptions as noted) are in /usr/local/gnu/bin/, so you will probably want to add that directory to your PATH, if it isn't there already.


If, after reading A Quick Introduction to C++, you still have questions about C++, feel free to post to the course newsgroup, ask in the discussion section, or ask during office hours. Oodles of information about C++ is available on-line from the C++ Virtual Library and other sites.

Students not familiar with C or C++ might find it worthwhile to invest in a book, for example,

The books by Stroustrup and Lippman are available for 7-day loan from Swain Library.

For people not experienced with pointers in C, here are some ugly but useful techniques:

Compiling Nachos

GNU make is used to automate the compilation process, so you won't need to become an expert on the dozens of command-line arguments to the compilers. Documentation is available via the make man page and via the Info facility in emacs (press Control-h i). The documentation can be intimidating, but don't worry: you don't need to become an expert on make for this project. Everything is already set up to compile the "skeleton" of Nachos. You will only need to make a few small changes to the Makefile to tell make about the procedures that you write. This will be discussed in the discussion section.

Be sure to use GNU make (/usr/local/gnu/bin/make, also called gmake), not Sun make (/usr/ccs/bin/make). After you copy nachos, please compile it before modifying the code. If it gives errors during compilation, figure out what in your environment is causing the errors before modifying the code.

Nachos can be compiled using g++, the GNU C++ compiler, or CC, Sun's C++ compiler. Edit Makfile.common to control which compiler is used. To use CC, the lines following "for SUN CC:" should be uncommented, and the lines following "for GNU g++" should be commented out. To use g++, the lines following "for SUN CC:" should be commented out, and the lines following "for GNU g++" should be uncommented. Object files produced by CC and g++ are incompatible, so whenever you switch from one compiler to the other, remove all object files; a good way to do this is to cd to the code directory and run make clean. Also, the two compilers use different system include files, so you should run make depend when switching between them.

Documentation on CC is available via the CC man page. Documentation on g++ is available via the g++ man page and via emacs' Info facility.

For each project, you compile nachos in an appropriate subdirectory of code. For example, in proj1, you will compile nachos in code/threads; in proj2+3, you will compile nachos in code/userprog. To compile nachos, cd to the appropriate directory and then run make nachos. When you change the file dependencies (e.g., by creating a new .h or .cc file, or by moving a function declaration or definition from one file to another), you need to run make depend before running make nachos (in the same directory). By default, running make in the code directory has the same efffect as running make depend and make nachos in several subdirectories of code; this is rarely a useful thing to do.

Occasionally people have trouble with #include. The typical symptom is the compiler complaining that some classes and variables are undefined when they are first used. A good way to debug these problems is to look at the code produced by the C preprocessor. You can do this using the -E command-line option to CC or gcc (instead of the usual -c option), which sends the preprocessor's output to standard output, instead of compiling it. When you look at (e.g.) addrspace.h, note that ADDRSPACE_H is #define'd before the declarations in addrspace.h are actually processed.

Cross-Compiling User Programs

To cross-compile user programs: cd to code/test and then use make (e.g., make all or make halt). The cross-compiler is for C programs, not C++ programs. Your user programs should not call functions defined in stdlib.h, stdio.h, etc., since Nachos does not support the system calls invoked by those library functions. Note that you are not implementing any system calls for managing a heap (such as UNIX brk and sbrk); thus, user programs running over Nachos do not have a heap.

code/test/Makefile sets PATH so that the cross-compiler can find the appropriate subprograms. Running the cross-compiler directly from your command-line won't work unless you set your PATH similarly, which would probably cause your other compilers to find the wrong versions of those subprograms. Thus, we recommend that you always use a Makefile to run the cross-compiler.

In cross-compiled programs, do not use declarations of the form

char name[] = "test";
char *name = "test";

Running Nachos

To run nachos (or any executable), you need to either give an explicit pathname (e.g., ./nachos instead of simply nachos) or add the name of the directory containing the executable to your PATH environment variable (by modifying the appropriate line in your .cshrc file). When a dot is used in your PATH as the name of a directory, it always refers to the current working directory. Generally, the nachos executable is in a different directory for each project, so the two easiest options are: (1) add a dot to your PATH, or (2) leave your PATH alone and use an explicit pathname.

Running under Solaris or Linux

You can now work under Solaris or Linux. The Linux port is new. I have run a few test programs on it, and it seems to work. If you notice any discrepancies between the two versions, please let me know.

Makfile.dep automatically determines which OS you are using. Object files and binaries produced under different OSs are incompatible. Also, different OSs use different include files, leading to different file dependencies. Thus, whenever you switch from one OS to the other:


The tags facility is very helpful for finding definitions of particular identifiers (variables, class names, methods, etc.) in large bodies of code. Use the etags command to create a "tags file" (also called "tags table"), which is a database describing where each identifier is defined in the code. For example, the "tags table" ~os/nachos-dfs/code/TAGS was created with the command
cd ~os/nachos-dfs/code; etags */*.cc */*.h
For more info, see the man page for etags.

Various editors (including emacs and xemacs) provide a tags facility. In emacs or xemacs, press Meta-. (that's "Meta period") to use the tags facility. The first time you do this, you will be prompted for the name of the tags file. After that, you simply enter the name of an identifier, and the editor will show you its definition, automatically loading the appropriate file into a buffer, if necessary.

As you edit the code---adding, deleting, and moving definitions of identifiers---you should occasionally re-run the etags command to update the tags table.


One way to debug is to add print statements. The Nachos code contains a DEBUG function to facilitate this. This function is declared in threads/utility.h and is controlled by the -d flag to nachos; the -d flag followed by a space and a series of debug flags (characters) cause the DEBUG statements with those debug flags to print a message when they are executed. See threads/utility.h for a description of the meanings of the current debug flags. You can print the current DEBUG statements by doing "fgrep DEBUG *h *cc". You might be tempted to add printf statements directly, instead of using DEBUG; this is not recommended, because printf does not flush stdout, and this can make the output of a multi-threaded program difficult to interpret. Introducing new debug flags and adding more DEBUG statements is helpful for debugging. The ASSERT macro, also declared in threads/utility.h, is also helpful. Source-level debuggers are powerful tools; you should use one. (Warning: Tracing across a call to SWITCH sometimes confuses the source-level debugger.) Some options:

dbx and workshop: These are Sun's debuggers. They have more features than the GNU debuggers. You'll need to add /opt/SUNWspro/bin/ to your PATH, if it isn't there already. You can use dbx via its built-in command-line interface. Most people prefer to use workshop, which is an integrated programming environment whose debugging facility is essentially dbx with a graphical user interface. For more information, see the man dbx, man workshop, and Using Sun WorkShop. If you use xemacs, an alternative is to use the xemacs interface to dbx (see the Tools and SPARCworks menus). A particularly useful feature is access checking (check -access in dbx, or use the Checks pull-down menu in workshop); for details, type help check in dbx or workshop
Warning: Sun's debuggers don't fully understand .o files produced by g++, so if you use Sun's debuggers, be sure to compile nachos with CC, not g++.

gdb and xxgdb: These debuggers, from GNU, are pretty good (and start up faster than workshop) but lack some of the features of the Sun debuggers, so I don't recommend using them, unless you are running nachos under Linux, in which case you have no choice.
Warning: GNU's debuggers don't fully understand .o files produced by CC, so if you use GNU debuggers, be sure to compile nachos with g++, not CC. Documentation on gdb is available via the Info facility in emacs (press Control-h i). Or, you can rely on gdb's extensive buit-in help facility; just run gdb, type help, then press Return. Various interfaces to gdb are available:

Overflow of Call Stacks

In the Nachos implementation of threads, each thread is assigned a small, fixed-size call stack (also called "execution stack"). If you declare large data structures to be automatic variables (e.g., int buf[1000];), the call stack will overflow, causing bizarre problems, such as segmentation faults. If that happens, either allocate those data structures on the heap, or increase the value of StackSize, defined in threads/thread.h.

Version Management Software

You might want to use version management software, such as CVS, both to undo changes that you later regretted and to avoid problems caused by multiple people editing the same file concurrently. Documentation on CVS is available in several forms: the cvs man page, the Info facility in emacs or xemacs (press Control-h i), and PostScript (Warning: this document is about 120 pages long!).

If you use CVS, you will want to set default ACLs for directories; here is more detailed info: CVS and ACLs.

Submitting Assignments

By default, all assignments in this course are due by the end (midnight) of the specified day.

To submit a preliminary design document: Email it to os@cs.indiana.edu or give a hardcopy to the instructor, by putting it under the door of LH201C or in the homework drop box near Lindley 215. If you use the homework drop box, be sure the instructor's name appears on the first page, so the staff knows to whom to give it.

To submit a programming assignment:

  1. Put your README and TESTCASE files in the appropriate directory: threads for proj1, userprog for proj2, vm for proj3, network for proj4.
  2. Run ~os/bin/zip-nachos (with appropriate command-line arguments) to create a .zip file containing all of your files for the submitted project. Run zip-nachos with no arguments to get a short help message describing its command-line arguments.
  3. Fill out this submission form (by overwriting the sample responses) and email it to os@cs.indiana.edu. The md5sum of the zip file is required, because the file timestamps maintained by Sun NFS can be modified arbitrarily using touch.


As mentioned on the
Project Guidelines page, to facilitate grading of each project, each team will meet with an A.I. to demo its nachos (i.e., run some testcases) and answer questions about the code. Each demo session proceeds as follows:
  1. The A.I. logs in as os, computes the md5sum of your .zip file for this project, and compares it to the value in your submission message, to verify that the file has not changed since you submitted the assignment.
  2. Unzip your .zip file for this project. This can be done in your directory or in ~os, as you prefer.
  3. The A.I. might ask you to insert some Yield statements in your code, to help check that your code would work correctly if kernel threads were pre-emptive.
  4. cd to the appropriate directory and run make nachos.
  5. Run ./nachos -rs seed on some testcases supplied by the A.I. and, if appropriate, on some testcases you wrote, using various values of seed.