You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

155 lines
3.3 KiB

#!/usr/bin/perl
#!/usr/local/bin/perl
use Getopt::Std;
#######################################################################
# checktrace - trace file consistency checker and balancer.
#
# Copyright (c) 2002, R. Bryant and D. O'Hallaron, All rights reserved.
# May not be used, modified, or copied without permission.
#
# This script reads a Malloc Lab trace file, checks it for consistency,
# and outputs a balanced version by appending any necessary free requests.
#
#######################################################################
$| = 1; # autoflush output on every print statement
#
# void usage(void) - print help message and terminate
#
sub usage
{
printf STDERR "$_[0]\n";
printf STDERR "Usage: $0 [-hs]\n";
printf STDERR "Options:\n";
printf STDERR " -h Print this message\n";
printf STDERR " -s Emit only a brief summary\n";
die "\n" ;
}
##############
# Main routine
##############
#
# Parse and check the command line arguments
#
getopts('hs');
if ($opt_h) {
usage("");
}
$summary = $opt_s;
#
# HASH keeps a running tally of outstanding alloc/realloc
# requests. When a free request is encountered, the corresponding
# hash entry is deleted. When we are finished reading the trace,
# what is left are the unmatched alloc/realloc requests.
#
%HASH = ();
# Read the trace header values
$heap_size = <STDIN>;
chomp($heap_size);
$num_blocks = <STDIN>;
chomp($num_blocks);
$old_num_ops = <STDIN>;
chomp($old_num_ops);
$weight = <STDIN>;
chomp($weight);
#
# Find any allocate requests that don't have a matching free requests
#
$linenum = 4;
$requestnum = 0;
while ($line = <STDIN>) {
chomp($line);
$linenum++;
($cmd, $id, $size) = split(" ", $line);
# ignore blank lines
if (!$cmd) {
next;
}
# save the line for output later
$lines[$requestnum++] = $line;
#ignore realloc requests, as long as they are preceeded by an alloc request
if ($cmd eq "r") {
if (!$HASH{$id}) {
die "$0: ERROR[$linenum]: realloc without previous alloc\n";
}
next;
}
if ($cmd eq "a" and $HASH{$id} eq "a") {
die "$0: ERROR[$linenum]: allocate with no intervening free.\n";
}
if ($cmd eq "a" and $HASH{$id} eq "f") {
die "$0: ERROR[$linenum]: reused ID $id.\n";
}
if ($cmd eq "f" and !exists($HASH{$id})) {
die "$0: ERROR[$linenum]: freeing unallocated block.\n";
next;
}
if ($cmd eq "f" and !$HASH{$id} eq "f") {
die "$0: ERROR[$linenum]: freeing already freed block.\n";
next;
}
if ($cmd eq "f") {
delete $HASH{$id};
}
else {
$HASH{$id} = $cmd;
}
}
#
# If called with -s argument , print a brief balance summary and exit
#
if ($summary) {
if (!%HASH) {
print "Balanced trace.\n";
}
else {
print "Unbalanced tree.\n";
}
exit;
}
#
# Output a balanced version of the trace
#
$new_ops = keys %HASH;
$new_num_ops = $old_num_ops + $new_ops;
print "$heap_size\n";
print "$num_blocks\n";
print "$new_num_ops\n";
print "$weight\n";
# print the old requests
foreach $item (@lines) {
print "$item\n";
}
# print a set of free requests that will balance the trace
foreach $key (sort keys %HASH) {
if ($HASH{$key} ne "a" and $HASH{$key} ne "r") {
die "$0: ERROR: Invalid free request in residue.\n";
}
print "f $key\n";
}
exit;