From 2b285747143381620ebf4fb37df37d90fbf25705 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 10 Dec 2004 06:24:57 +0000 Subject: [PATCH] Add "real-time" option to pintos utility and document its usage. --- doc/filesys.texi | 6 +++++- doc/threads.texi | 23 ++++++++++++++++++----- src/utils/pintos | 25 ++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/doc/filesys.texi b/doc/filesys.texi index ab97148..767cfa3 100644 --- a/doc/filesys.texi +++ b/doc/filesys.texi @@ -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 diff --git a/doc/threads.texi b/doc/threads.texi index a544b78..2e00326 100644 --- a/doc/threads.texi +++ b/doc/threads.texi @@ -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 diff --git a/src/utils/pintos b/src/utils/pintos index 9b3d0e7..1242698 100755 --- a/src/utils/pintos +++ b/src/utils/pintos @@ -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') { -- 2.30.2