For Lab 1 and future nachos assignments you may want to add command line flags to change what nachos does without recompiling. For example, in Lab 1 you might want to use command line arguments to trigger specific yield points in your program.

Rather than coding in different command line flags every time, here's some code that lets you assign a value to an arbitrary integer global variable from the command line.

Example: nachos -set my_global_name 3

assigns the value 3 to the global integer 'my_global_name' in your nachos program before running the tests. You can use this to set the value of any variable you want, but the variable (e.g., my_global_name) MUST be a global integer, i.e., a data item declared as an int outside of any procedure scope.

WARNING: C++ constructors for static objects (static instances of classes) run BEFORE the command line arguments are parsed. This means that a static C++ constructor that uses the integer (e.g., my_global_name above) will not see the value '3' you set on the command line. Static objects are a bad idea anyway, but if you use them, be aware that their constructors run before any other initialization code in your program.

Grab a modified version of threads/system.cc from ~dca/public/system.cc on acpub, or cut-and-paste the code below and add it to system.cc yourself. Also, edit code/Makefile.dep and add "-lelf" to the end of the LDFLAGS definition.

If you want a better idea of how this code works, try the "man nlist" and "man elf" commands at a UNIX prompt.


at the top of threads/system.cc, add:

#include < nlist.h >
char *_programname;
void Umem_SetInt(char *, int);
edit Initialize(int argc, char **argv), add:
_programname = argv[0];
before the 'for' loop, and
if (!strcmp(*argv, "-set")) {
      Umem_SetInt(*(argv + 1), atoi(*(argv + 2))); // set a global
      argCount = 2;
}
between the "argCount = 1" and "if (!strcmp(*argv, "-d")) {" lines.

and at the end of system.cc, add:

//----------------------------------------------------------------------
// Umem_SetInt
//      Allow the user to assign a value to an arbitrary integer global
//      variable from the command line.
//----------------------------------------------------------------------

void
Umem_SetInt(char *varname, int value)
{
     struct nlist nl[2];

     nl[0].n_name = varname;
     nl[1].n_name = 0;
     if ((nlist(_programname, nl) < 0) || !nl[0].n_value) {
          if (!nl[0].n_value)
               fprintf(stderr, "error setting variable %s: doesn't exist\n", varname);
          else {
               fprintf(stderr, "error setting variable %s:", varname);
               perror("nlist");
          }
          exit(1);
     }
     *(int *)nl[0].n_value = value;
}