193 lines
4.0 KiB
Perl
Executable File
193 lines
4.0 KiB
Perl
Executable File
#! /usr/bin/perl -W
|
||
#
|
||
# Adam Lackorzynski <adam@os.inf.tu-dresden.de>
|
||
#
|
||
# Input to this script is the output of dumpmapdbobjs from Fiasco-jdb
|
||
# Output of this script is a dot graph
|
||
#
|
||
# Convert to SVG with e.g.:
|
||
# fdp -Gmclimit=200.0 -Gnslimit=500.0 -Gratio=0.7 \
|
||
# -Tsvg -o x.svg x.dot
|
||
#
|
||
# To be improved...
|
||
|
||
use strict;
|
||
|
||
my $ignore = 1;
|
||
my $line = 0;
|
||
#my %spaces;
|
||
my %intasks;
|
||
my %kobjstype;
|
||
my %names;
|
||
my %obj_to_connector;
|
||
my %obj_to_root_space;
|
||
|
||
my %obj_colors = (
|
||
'Task' => 'red',
|
||
'Thread' => 'green',
|
||
'Sched' => 'blue',
|
||
'Factory' => 'yellow',
|
||
'Gate' => 'magenta',
|
||
);
|
||
|
||
while (<>)
|
||
{
|
||
chomp;
|
||
++$line;
|
||
s/
|
||
$//;
|
||
if (/^========= OBJECT DUMP BEGIN ===============/)
|
||
{
|
||
$ignore = 0;
|
||
}
|
||
elsif (/^========= OBJECT DUMP END ===============/)
|
||
{
|
||
last; # done, we only consider the first one
|
||
}
|
||
elsif (!$ignore)
|
||
{
|
||
my $dbgid;
|
||
my $obj_type;
|
||
my $intask;
|
||
my $name;
|
||
$dbgid = $1 if /^([\da-fA-F]+)\s+/;
|
||
$obj_type = $1 if /\s\[([^\s\]]+)/;
|
||
$intask = $1 if /intask=(\S+)/;
|
||
$name = $1 if /\s{([^\s}]+)/;
|
||
|
||
#print "$line: $_\n";
|
||
if (not defined $dbgid or not defined $obj_type)
|
||
{
|
||
print "ERROR: parse or content error in line $line: $_\n";
|
||
last;
|
||
}
|
||
|
||
$obj_type =~ s/\[.*?m//g;
|
||
|
||
$obj_to_connector{$dbgid} = $1
|
||
if $obj_type eq 'Gate' and (/ D=([\da-fA-Z]+)/);
|
||
$obj_to_connector{$dbgid} = $1
|
||
if $obj_type eq 'IRQ' and (/ T=([\da-fA-Z]+)/);
|
||
$obj_to_connector{$dbgid} = $1
|
||
if $obj_type eq 'Thread' and (/ S=D:([\da-fA-Z]+)/);
|
||
|
||
$kobjstype{$dbgid} = $obj_type;
|
||
$names{$dbgid} = $name if defined $name;
|
||
|
||
if (defined $intask)
|
||
{
|
||
$intasks{$dbgid} = [ map { /^\[(.+)\]$/ } split(/,/, $intask) ];
|
||
|
||
$intasks{$dbgid}[0] =~ /^([^:]+)/;
|
||
$obj_to_root_space{$dbgid} = $1;
|
||
}
|
||
}
|
||
}
|
||
|
||
sub id_to_objtype($)
|
||
{
|
||
my $a = shift;
|
||
return "$kobjstype{$a}" if defined $kobjstype{$a};
|
||
return $a;
|
||
}
|
||
|
||
sub id_to_name($)
|
||
{
|
||
my $a = shift;
|
||
return "$a".":".id_to_objtype($a).":".$names{$a} if defined $names{$a};
|
||
return $a;
|
||
}
|
||
|
||
print "digraph A {\n";
|
||
|
||
if (0)
|
||
{
|
||
foreach my $o (keys %kobjstype)
|
||
{
|
||
print " o$o [label = \"", id_to_objtype($o), "\"];\n";
|
||
}
|
||
}
|
||
|
||
foreach my $t (keys %kobjstype)
|
||
{
|
||
next unless
|
||
$kobjstype{$t} eq 'Task';
|
||
|
||
print " subgraph cluster_$t { label = \"", id_to_name($t), "\";".
|
||
" style=filled; \n";
|
||
|
||
foreach my $o (keys %intasks)
|
||
{
|
||
foreach my $i (@{$intasks{$o}})
|
||
{
|
||
$i =~ /([\da-fA-F]+):(\d+)/;
|
||
my $space = $1;
|
||
my $lvl = $2;
|
||
|
||
if ($t eq $space)
|
||
{
|
||
print " s$space"."o$o [label = \"".id_to_name($o)."\"";
|
||
#print " s$space"."o$o [label = \"$o\"";
|
||
print ",color=$obj_colors{$kobjstype{$o}}"
|
||
if defined $obj_colors{$kobjstype{$o}};
|
||
print "];\n";
|
||
}
|
||
|
||
#print "$o: $space - $lvl\n";
|
||
}
|
||
}
|
||
|
||
print " }\n";
|
||
}
|
||
|
||
# mapping correlations
|
||
foreach my $o (keys %intasks)
|
||
{
|
||
my $lvl = 0;
|
||
my @stack;
|
||
|
||
foreach my $i (@{$intasks{$o}})
|
||
{
|
||
$i =~ /([\da-fA-F]+):(\d+)/;
|
||
my $space = $1;
|
||
my $l = $2;
|
||
|
||
#print STDERR "$i -- l=$l\n";
|
||
|
||
$stack[$l] = $space;
|
||
|
||
if ($l > 0)
|
||
{
|
||
print " s$stack[$l-1]o$o -> s$stack[$l]o$o";
|
||
print "[color=$obj_colors{$kobjstype{$o}}]"
|
||
if defined $obj_colors{$kobjstype{$o}};
|
||
print ";\n";
|
||
}
|
||
#print "$o: $space - $l\n";
|
||
}
|
||
}
|
||
|
||
# connect tasks to cluster-boxes
|
||
foreach my $t (keys %kobjstype)
|
||
{
|
||
next unless
|
||
$kobjstype{$t} eq 'Task';
|
||
|
||
if ($obj_to_root_space{$t} ne $t)
|
||
{
|
||
print " s$obj_to_root_space{$t}o$t -> cluster_$t [style=dashed];\n";
|
||
}
|
||
}
|
||
|
||
|
||
# connect gates/irqs to their threads
|
||
foreach my $g (keys %obj_to_connector)
|
||
{
|
||
my $s1 = $obj_to_root_space{$g};
|
||
my $s2 = $obj_to_root_space{$obj_to_connector{$g}};
|
||
my $o = $obj_to_connector{$g};
|
||
print " s${s1}o$g -> s${s2}o$o [style=dotted];\n"
|
||
if defined $s1 and defined $s1;
|
||
}
|
||
|
||
print "}\n";
|