# -*- perl -*-
use strict;
use warnings;
sub mlfqs_expected_load {
my ($ready, $recent_delta) = @_;
my (@load_avg) = 0;
my (@recent_cpu) = 0;
my ($load_avg) = 0;
my ($recent_cpu) = 0;
for my $i (0$#$ready) {
$load_avg = (59/60) * $load_avg + (1/60) * $ready->[$i];
push (@load_avg, $load_avg);
if (defined $recent_delta->[$i]) {
my ($twice_load) = $load_avg * 2;
my ($load_factor) = $twice_load / ($twice_load + 1);
$recent_cpu = ($recent_cpu + $recent_delta->[$i]) * $load_factor;
push (@recent_cpu, $recent_cpu);
}
}
return (@load_avg, @recent_cpu);
}
sub mlfqs_expected_ticks {
my (@nice) = @_;
my ($thread_cnt) = scalar (@nice);
my (@recent_cpu) = (0) x $thread_cnt;
my (@slices) = (0) x $thread_cnt;
my (@fifo) = (0) x $thread_cnt;
my ($next_fifo) = 1;
my ($load_avg) = 0;
for my $i (1750) {
if ($i % 25 == 0) {
# Update load average.
$load_avg = (59/60) * $load_avg + (1/60) * $thread_cnt;
# Update recent_cpu.
my ($twice_load) = $load_avg * 2;
my ($load_factor) = $twice_load / ($twice_load + 1);
$recent_cpu[$_] = $recent_cpu[$_] * $load_factor + $nice[$_]
foreach 0($thread_cnt 1);
}
# Update priorities.
my (@priority);
foreach my $j (0($thread_cnt 1)) {
my ($priority) = int ($recent_cpu[$j] / 4 + $nice[$j] * 2);
$priority = 0 if $priority < 0;$priority = 63 if $priority > 63;
push (@priority, $priority);
}
# Choose thread to run.
my $max = 0;
for my $j (1$#priority) {
if ($priority[$j] < $priority[$max]|| ($priority[$j] == $priority[$max]&& $fifo[$j] < $fifo[$max])) {$max = $j;}}$fifo[$max] = $next_fifo++;# Run thread.$recent_cpu[$max] += 4;$slices[$max] += 4;}return @slices;}sub check_mlfqs_fair {my ($nice, $maxdiff) = @_;our ($test);my (@output) = read_text_file (“$test.output”);common_checks (“run”, @output);@output = get_core_output (“run”, @output);my (@actual);local ($_);foreach (@output) {my ($id, $count) = /Thread (d+) received (d+) ticks./ or next;$actual[$id] = $count;}my (@expected) = mlfqs_expected_ticks (@$nice);mlfqs_compare (“thread”, “%d”, @actual, @expected, $maxdiff, [0, $#$nice, 1], “Some tick counts were missing or differed from those ” . “expected by more than $maxdiff.”);pass;}sub mlfqs_compare {my ($indep_var, $format,$actual_ref, $expected_ref, $maxdiff, $t_range, $message) = @_;my ($t_min, $t_max, $t_step) = @$t_range;my ($ok) = 1;for (my ($t) = $t_min; $t <= $t_max; $t += $t_step) {my ($actual) = $actual_ref->[$t];
my ($expected) = $expected_ref->[$t];
$ok = 0, last
if !defined ($actual) || abs ($actual $expected) > $maxdiff + .01;
}
return if $ok;
print $message
;
mlfqs_row ($indep_var, actual, <->, expected, explanation);
mlfqs_row (, , , , – x 40);
for (my ($t) = $t_min; $t <= $t_max; $t += $t_step) {my ($actual) = $actual_ref->[$t];
my ($expected) = $expected_ref->[$t];
my ($diff, $rationale);
if (!defined $actual) {
$actual = undef ;
$diff = ;
$rationale = Missing value.;
} else {
my ($delta) = abs ($actual $expected);
if ($delta > $maxdiff + .01) {
my ($excess) = $delta $maxdiff;
if ($actual > $expected) {
$diff = >>>;
$rationale = sprintf Too big, by $format., $excess;
} else {
$diff = <<<‘;$rationale = sprintf “Too small, by $format.”, $excess;}} else {$diff = ‘ = ‘;$rationale = ”;}$actual = sprintf ($format, $actual);}$expected = sprintf ($format, $expected);mlfqs_row ($t, $actual, $diff, $expected, $rationale);}fail;}sub mlfqs_row {printf “%6s %8s %3s %-8s %s
“, @_;}1;
Reviews
There are no reviews yet.