Add "real-time" option to pintos utility and document its usage.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 10 Dec 2004 06:24:57 +0000 (06:24 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 10 Dec 2004 06:24:57 +0000 (06:24 +0000)
doc/filesys.texi
doc/threads.texi
src/utils/pintos

index ab971487c31637acafc78ebc65583a5ea5abf7eb..767cfa3a257703de6196da298d9bcbd858a3d91f 100644 (file)
@@ -266,7 +266,11 @@ Note that write-behind makes your filesystem more fragile in the face
 of crashes.  Therefore, you should
 periodically write all cached blocks to disk.  If you have
 @func{timer_sleep} from the first project working, this is an
-excellent application for it.
+excellent application for it.  (If you're still using the base
+implementation of @func{timer_sleep}, be aware that it busy-waits, which
+is not an acceptable solution.) If @func{timer_sleep}'s delays seem too
+short or too long, reread the explanation of the @option{-r} option to
+@command{pintos} (@pxref{Debugging versus Testing}).
 
 Likewise, read-ahead is only really useful when done asynchronously.
 That is, if a process wants disk block 1 from the file, it needs to
index a544b78f06522fd89a27a76a2ea0c598b0bbbf3b..2e0032657560c8be1799fcb5b8906e1beb8ce077 100644 (file)
@@ -295,7 +295,8 @@ program twice and have it do exactly the same thing.  On second and
 later runs, you can make new observations without having to discard or
 verify your old observations.  This property is called
 ``reproducibility.''  The simulator we use, Bochs, can be set up for
-reproducibility, and that's the way that @command{pintos} invokes it.
+reproducibility, and that's the way that @command{pintos} invokes it
+by default.
 
 Of course, a simulation can only be reproducible from one run to the
 next if its input is the same each time.  For simulating an entire
@@ -313,15 +314,23 @@ thread switches.  That means that running the same test several times
 doesn't give you any greater confidence in your code's correctness
 than does running it only once.
 
-So, to make your code easier to test, we've added a feature to Bochs
-that makes timer interrupts come at random intervals, but in a
-perfectly predictable way.  In particular, if you invoke
-@command{pintos} with the option @option{-j @var{seed}}, timer
+So, to make your code easier to test, we've added a feature, called
+``jitter,'' to Bochs, that makes timer interrupts come at random
+intervals, but in a perfectly predictable way.  In particular, if you
+invoke @command{pintos} with the option @option{-j @var{seed}}, timer
 interrupts will come at irregularly spaced intervals.  Within a single
 @var{seed} value, execution will still be reproducible, but timer
 behavior will change as @var{seed} is varied.  Thus, for the highest
 degree of confidence you should test your code with many seed values.
 
+On the other hand, when Bochs runs in reproducible mode, timings are not
+realistic, meaning that a ``one-second'' delay may be much shorter or
+even much longer than one second.  You can invoke @command{pintos} with
+a different option, @option{-r}, to make it set up Bochs for realistic
+timings, in which a one-second delay should take approximately one
+second of real time.  Simulation in real-time mode is not reproducible,
+and options @option{-j} and @option{-r} are mutually exclusive.
+
 @node Tips
 @section Tips
 
@@ -383,6 +392,10 @@ in milliseconds or another unit.  There are @code{TIMER_FREQ} timer
 ticks per second, where @code{TIMER_FREQ} is a macro defined in
 @code{devices/timer.h}.
 
+If your delays seem too short or too long, reread the explanation of the
+@option{-r} option to @command{pintos} (@pxref{Debugging versus
+Testing}).
+
 @node Problem 1-2 Join
 @section Problem 1-2: Join
 
index 9b3d0e7adecc1a5d29b21bacf270e1add5233b16..124269848c0926063935cd0e4a7d897b162a310d 100755 (executable)
@@ -8,7 +8,7 @@ our (@disks) = ("os.dsk", "fs.dsk", "scratch.dsk", "swap.dsk");
 our ($sim);
 our ($debug);
 our ($vga);
-our ($jitter);
+our ($jitter, $realtime);
 
 use Getopt::Long qw(:config require_order bundling);
 GetOptions ("sim=s" => sub { set_sim (@_) },
@@ -24,7 +24,8 @@ GetOptions ("sim=s" => sub { set_sim (@_) },
            "run|get|put|make-disk" => \&cmd_option,
            
            "m|memory=i" => \$mem,
-           "j|jitter=i" => \$jitter,
+           "j|jitter=i" => sub { set_jitter (@_) },
+           "r|realtime" => sub { set_realtime () },
            
            "v|no-vga" => sub { set_vga ('none'); },
            "s|no-serial" => sub { $serial_out = 0; },
@@ -64,6 +65,19 @@ sub set_vga {
     $vga = $new_vga;
 }
 
+sub set_jitter {
+    my ($new_jitter) = @_;
+    die "--realtime conflicts with --jitter\n" if defined $realtime;
+    die "different --jitter already defined\n"
+       if defined $jitter && $jitter != $new_jitter;
+    $jitter = $new_jitter;
+}
+
+sub set_realtime {
+    die "--realtime conflicts with --jitter\n" if defined $jitter;
+    $realtime = 1;
+}
+
 sub cmd_option {
     # Force an end to option processing, as with --.
     die ("!FINISH");
@@ -165,6 +179,7 @@ sub usage {
     print "  -t, --terminal   Display VGA in terminal (Bochs only)\n";
     print "VM options:\n";
     print "  -j SEED          Randomize timer interrupts (Bochs only)\n";
+    print "  -r, --realtime   Use realistic, but not reproducible, timings\n";
     print "  -m, --mem=MB     Run VM with MB megabytes of physical memory\n";
     print "Disk options:\n";
     print "  --os-disk=DISK    Set OS disk file (default: os.dsk)\n";
@@ -222,7 +237,11 @@ sub run_vm {
        print BOCHSRC bochs_disk_line ("ata1-slave", $disks[3]);
        print BOCHSRC "boot: c\n";
        print BOCHSRC "ips: 1000000\n";
-       print BOCHSRC "clock: sync=none, time0=0\n";
+       if (!$realtime) {
+           print BOCHSRC "clock: sync=none, time0=0\n";
+       } else {
+           print BOCHSRC "clock: sync=realtime, time0=0\n";
+       }
        print BOCHSRC "megs: $mem\n";
        print BOCHSRC "log: bochsout.txt\n";
        if ($vga ne 'terminal') {