Use runtime options instead of conditional compilation for MLFQS,
[pintos-anon] / grading / threads / run-tests
index 096bec0a08285bbf8cc034da210154661680d10d..bd705e43b2da871acc5e51a3a5d034e8e9bcd646 100755 (executable)
@@ -21,17 +21,10 @@ our (%details);
 our (%result);
 our ($action);
 
-parse_cmd_line ();
-
-# Default set of tests.
-@TESTS = ("alarm-single", "alarm-multiple", "alarm-zero", "alarm-negative",
-         "join-simple",
-         "join-quick", "join-multiple", "join-nested",
-         "join-dummy", "join-invalid", "join-no",
-         "priority-preempt", "priority-fifo", "priority-donate-one",
-         "priority-donate-multiple", "priority-donate-nest",
-         "mlfqs-on", "mlfqs-off")
-    unless @TESTS > 0;
+parse_cmd_line qw (alarm-single alarm-multiple alarm-zero alarm-negative
+                  priority-preempt priority-fifo priority-donate-one
+                  priority-donate-multiple priority-donate-nest
+                  mlfqs-on mlfqs-off);
 
 clean_dir (), exit if $action eq 'clean';
 
@@ -41,38 +34,43 @@ exit if $action eq 'extract';
 build (); 
 exit if $action eq 'build';
 
-run_and_grade_tests (); 
-grade_mlfqs_speedup ();
-grade_mlfqs_priority ();
+run_and_grade_tests ();
+if (defined ($result{'mlfqs-on'}) && defined ($result{'mlfqs-off'})) {
+    grade_mlfqs_speedup ();
+    grade_mlfqs_priority ();
+}
 write_grades (); 
 write_details ();
-exit if $action eq 'test';
+exit success () if $action eq 'test';
 
 assemble_final_grade ();
-exit if $action eq 'assemble';
+exit success () if $action eq 'assemble';
 
 die "Don't know how to '$action'";
 
 # Runs $test in directory output/$test.
 # Returns 'ok' if it went ok, otherwise an explanation.
 sub run_test {
-    # Change constants.h if necessary.
-    my ($defines) = $test ne 'mlfqs-on' ? "" : "#define MLFQS 1\n";
-    if ($defines ne snarf ("pintos/src/constants.h")) {
-       open (CONSTANTS, ">pintos/src/constants.h");
-       print CONSTANTS $defines;
-       close (CONSTANTS);
-    }
-
     # Changes devices/timer.c if necessary.
     my ($new_time_slice) = $test eq 'priority-fifo' ? 100 : 1;
-    my (@timer) = snarf ("pintos/src/devices/timer.c");
-    if (!grep (/^\#define TIME_SLICE $new_time_slice$/, @timer)) {
-       @timer = grep (!/^\#define TIME_SLICE/, @timer);
-       unshift (@timer, "#define TIME_SLICE $new_time_slice");
-       open (TIMER, ">pintos/src/devices/timer.c");
-       print TIMER map ("$_\n", @timer);
-       close (TIMER);
+    my (@timer_c) = snarf ("pintos/src/devices/timer.c");
+    if (!grep (/^\#define TIME_SLICE $new_time_slice$/, @timer_c)) {
+       @timer_c = grep (!/^\#define TIME_SLICE/, @timer_c);
+       unshift (@timer_c, "#define TIME_SLICE $new_time_slice");
+       open (TIMER_C, ">pintos/src/devices/timer.c");
+       print TIMER_C map ("$_\n", @timer_c);
+       close (TIMER_C);
+    }
+
+    # Changes devices/timer.h if necessary.
+    my ($new_timer_freq) = $test eq 'priority-fifo' ? 19 : 100;
+    my (@timer_h) = snarf ("pintos/src/devices/timer.h");
+    if (!grep (/^\#define TIMER_FREQ $new_time_slice$/, @timer_h)) {
+       @timer_h = grep (!/^\#define TIMER_FREQ/, @timer_h);
+       unshift (@timer_h, "#define TIMER_FREQ $new_timer_freq");
+       open (TIMER_H, ">pintos/src/devices/timer.h");
+       print TIMER_H map ("$_\n", @timer_h);
+       close (TIMER_H);
     }
 
     # Copy in the new test.c and delete enough files to ensure a full rebuild.
@@ -96,8 +94,11 @@ sub run_test {
     xsystem ("cp pintos/src/threads/build/os.dsk output/$test");
 
     # Run.
-    my ($timeout) = $test !~ /^mlfqs/ ? 10 : 600;
-    return run_pintos ("cd pintos/src/threads/build && pintos -v run -q",
+    my ($timeout) = $test !~ /^mlfqs/ ? 15 : 600;
+    my (@command) = ("-v", "run", "-q");
+    push (@command, "-o mlfqs") if $test eq 'mlfqs-on';
+    return run_pintos (\@command,
+                      CHDIR => "pintos/src/threads/build",
                       LOG => "$test/run",
                       TIMEOUT => $timeout);
 }
@@ -150,55 +151,6 @@ sub grade_alarm_negative {
     die "Crashed in timer_sleep()\n" if !grep (/^Success\.$/, @output);
 }
 
-sub grade_join_invalid {
-    my (@output) = @_;
-    verify_common (@output);
-    grep (/Testing invalid join/, @output) or die "Test didn't start\n";
-    grep (/Invalid join test done/, @output) or die "Test didn't complete\n";
-}
-
-sub grade_join_no {
-    my (@output) = @_;
-    verify_common (@output);
-    grep (/Testing no join/, @output) or die "Test didn't start\n";
-    grep (/No join test done/, @output) or die "Test didn't complete\n";
-}
-
-sub grade_join_multiple {
-    my (@output) = @_;
-
-    verify_common (@output);
-    my (@t);
-    $t[4] = $t[5] = $t[6] = -1;
-    local ($_);
-    foreach (@output) {
-       my ($idx) = /^Thread (\d+)/ or next;
-       my ($iter) = /iteration (\d+)$/;
-       $iter = 5 if /done!$/;
-       die "Malformed output\n" if !defined $iter;
-       if ($idx == 6) {
-           die "Thread 6 started before either other thread finished\n"
-               if $t[4] < 5 && $t[5] < 5;
-           die "Thread 6 started before thread 4 finished\n"
-               if $t[4] < 5;
-           die "Thread 6 started before thread 5 finished\n"
-               if $t[5] < 5;
-       }
-       die "Thread $idx out of order output\n" if $t[$idx] != $iter - 1;
-       $t[$idx] = $iter;
-    }
-
-    my ($err) = "";
-    for my $idx (4, 5, 6) {
-       if ($t[$idx] == -1) {
-           $err .= "Thread $idx did not run at all\n";
-       } elsif ($t[$idx] != 5) {
-           $err .= "Thread $idx only completed $t[$idx] iterations\n";
-       }
-    }
-    die $err if $err ne '';
-}
-
 sub grade_priority_fifo {
     my (@output) = @_;