From: Pierre Veyre Date: Sun, 6 Oct 2013 14:39:14 +0000 (+0200) Subject: Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid X-Git-Tag: v3_9_90~40 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/67c91d5b8652b0e76801e9cfc7d965a360237152?hp=b30d93ae03db486f298e28f8abfe908e6b71ce02 Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid --- diff --git a/buildtools/Cmake/Scripts/tesh.pl b/buildtools/Cmake/Scripts/tesh.pl index a7e5ddc885..31acb42b13 100755 --- a/buildtools/Cmake/Scripts/tesh.pl +++ b/buildtools/Cmake/Scripts/tesh.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl eval 'exec perl -S $0 ${1+"$@"}' - if $running_under_some_shell; + if $running_under_some_shell; =encoding UTF-8 @@ -16,8 +16,15 @@ B [I] I my($bindir)="."; my($srcdir)="."; my($timeout)=0; +my($time_to_wait)=0; my $path = $0; my $OS; +my $enable_coverage=0; +my $tesh_file; +my $tesh_name; +my $error=0; +my $exitcode=0; + $path =~ s|[^/]*$||; push @INC,$path; @@ -27,115 +34,131 @@ use Term::ANSIColor; use IPC::Open3; if($^O eq "linux"){ - $OS = "UNIX"; + $OS = "UNIX"; } else{ - $OS = "WIN"; + $OS = "WIN"; } sub trim($) { - my $string = shift; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - return $string; + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; } -print "OS: ".$OS."\n"; - # make sure we received a tesh file -scalar @ARGV > 0 || die "Usage:\n tesh [*options*] *tesh_file*\n"; +scalar @ARGV > 0 || die "Usage:\n tesh [*options*] *tesh_file*\n"; #Add current directory to path $ENV{PATH} = "$ENV{PATH}:."; - ## ## Command line option handling ## # option handling helper subs sub cd_cmd { - my $directory=$_[1]; - if (-e $directory && -d $directory) { - chdir("$directory"); - print "[Tesh/INFO] change directory to $directory\n"; - } elsif (-e $directory) { - die "[Tesh/CRITICAL] Cannot change directory to '$directory': it is not a directory\n"; - } else { - die "[Tesh/CRITICAL] Cannot change directory to '$directory': no such directory\n"; - } -} - -sub timeout_cmd{ - $timeout=$_[1]; + my $directory=$_[1]; + my $failure=1; + if (-e $directory && -d $directory) { + chdir("$directory"); + print "[Tesh/INFO] change directory to $directory\n"; + $failure=0; + } elsif (-e $directory) { + print "Cannot change directory to '$directory': it is not a directory\n"; + } else { + print "Chdir to $directory failed: No such file or directory\n"; + } + if($failure==1){ + $error=1; + $exitcode=4; + print "Test suite `$tesh_file': NOK (system error)\n"; + exit 4; + } } sub setenv_cmd { - my($var,$ctn); - if ($_[0] =~ /^(.*)=(.*)$/) { - ($var,$ctn)=($1,$2); - }elsif ($_[1] =~ /^(.*)=(.*)$/) { - ($var,$ctn)=($1,$2); - } else { - die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n"; + my($var,$ctn); + if ($_[0] =~ /^(.*)=(.*)$/) { + ($var,$ctn)=($1,$2); + }elsif ($_[1] =~ /^(.*)=(.*)$/) { + ($var,$ctn)=($1,$2); + } else { + die "[Tesh/CRITICAL] Malformed argument to setenv: expected 'name=value' but got '$_[1]'\n"; + } + + if($var =~ /bindir/){ + print "[Tesh/INFO] setenv $var=$ctn\n"; + $bindir = $ctn; } - - if($var =~ /bindir/){ - print "[Tesh/INFO] setenv $var=$ctn\n"; - $bindir = $ctn; - } - else - { - if($var =~ /srcdir/){ - $srcdir = $ctn; - } - else{ - $ENV{$var} = $ctn; - print "[Tesh/INFO] setenv $var=$ctn\n"; - } - } + else + { + if($var =~ /srcdir/){ + $srcdir = $ctn; + } + else{ + $ENV{$var} = $ctn; + print "[Tesh/INFO] setenv $var=$ctn\n"; + } + } } # Main option parsing sub -my $tesh_file; + sub get_options { - # remove the tesh file from the ARGV used - my @ARGV = @_; - $tesh_file = pop @ARGV; - - # temporary arrays for GetOption - my @verbose = (); - my @cfg; - my $log; # ignored - - my %opt = ( - "help" => 0, - "debug" => 0, - "verbose" => 0 - ); - - Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); - - GetOptions( - 'help|h' => \$opt{'help'}, - - 'verbose|v' => \@verbose, - 'debug|d' => \$opt{"debug"}, - - 'cd=s' => \&cd_cmd, - 'timeout=s' => \&timeout_cmd, - 'setenv=s' => \&setenv_cmd, - 'cfg=s' => \@cfg, - 'log=s' => \$log, - ); - - $opt{'verbose'} = scalar @verbose; - foreach (@cfg) { - $opt{'cfg'} .= " --cfg=$_"; - } - return %opt; + # remove the tesh file from the ARGV used + my @ARGV = @_; + $tesh_file = pop @ARGV; + + # temporary arrays for GetOption + my @verbose = (); + my @cfg; + my $log; # ignored + + + my %opt = ( + "help" => 0, + "debug" => 0, + "verbose" => 0 + ); + + Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); + + GetOptions( + 'help|h' => \$opt{'help'}, + + 'verbose|v' => \@verbose, + 'debug|d' => \$opt{"debug"}, + + 'cd=s' => \&cd_cmd, + 'timeout=s' => \$opt{'timeout'}, + 'setenv=s' => \&setenv_cmd, + 'cfg=s' => \@cfg, + 'log=s' => \$log, + 'enable-coverage+' => \$enable_coverage, + ); + + if($enable_coverage){ + print "Enable coverage\n"; + } + + unless($tesh_file=~/(.*)\.tesh/){ + $tesh_file="(stdin)"; + $tesh_name="(stdin)"; + print "Test suite from stdin\n"; + }else{ + $tesh_name=$1; + print "Test suite `$tesh_name'\n"; + } + + $opt{'verbose'} = scalar @verbose; + foreach (@cfg) { + $opt{'cfg'} .= " --cfg=$_"; + } + return %opt; } my %opts = get_options(@ARGV); @@ -143,12 +166,10 @@ my %opts = get_options(@ARGV); ## ## File parsing ## -my($sort)=0; my($nb_arg)=0; my($old_buffer); my($linebis); my($SIGABRT)=0; -my($no_output_ignore)=1; my($verbose)=0; my($return)=-1; my($pid); @@ -156,266 +177,382 @@ my($result); my($result_err); my($forked); my($config)=""; - my($tesh_command)=0; my(@buffer_tesh)=(); -eval { - use POSIX; - sub exit_status { - my $status = shift; - if (POSIX::WIFEXITED($status)) { - return "returned code ".POSIX::WEXITSTATUS($status); - } elsif (POSIX::WIFSIGNALED($status)) { - return "got signal ".$SIG{POSIX::WTERMSIG($status)}; - } - return "Unparsable status. Is the process stopped?"; +#eval { + use POSIX; + + sub exit_status { + my $status = shift; + if (POSIX::WIFEXITED($status)) { + return "returned code ".POSIX::WEXITSTATUS($status); + } elsif (POSIX::WIFSIGNALED($status)) { + my $code; + if (POSIX::WTERMSIG($status) == SIGINT){$code="SIGINT"; } + elsif (POSIX::WTERMSIG($status) == SIGTERM) {$code="SIGTERM"; } + elsif (POSIX::WTERMSIG($status) == SIGKILL) {$code= "SIGKILL"; } + elsif (POSIX::WTERMSIG($status) == SIGABRT) {$code="SIGABRT"; } + elsif (POSIX::WTERMSIG($status) == SIGSEGV) {$code="SIGSEGV" ;} + $exitcode=POSIX::WTERMSIG($status)+4; + return "got signal $code"; } -}; -if ($@) { # no POSIX available? - warn "POSIX not usable to parse the return value of forked child: $@\n"; - sub exit_status { - return "returned code 0"; - } -} + return "Unparsable status. Is the process stopped?"; + } +#}; +#if ($@) { # no POSIX available? +# warn "POSIX not usable to parse the return value of forked child: $@\n"; +# sub exit_status { +# return "returned code -1 $@ "; +# } +#} sub exec_cmd { - my %cmd = %{$_[0]}; - if ($opts{'debug'}) { - print "IN BEGIN\n"; - map {print " $_"} @{$cmd{'in'}}; - print "IN END\n"; - print "OUT BEGIN\n"; - map {print " $_"} @{$cmd{'out'}}; - print "OUT END\n"; - print "CMD: $cmd{'cmd'}\n"; + my %cmd = %{$_[0]}; + if ($opts{'debug'}) { + print "IN BEGIN\n"; + map {print " $_"} @{$cmd{'in'}}; + print "IN END\n"; + print "OUT BEGIN\n"; + map {print " $_"} @{$cmd{'out'}}; + print "OUT END\n"; + print "CMD: $cmd{'cmd'}\n"; + } + + # cleanup the command line + if($OS eq "WIN"){ + $cmd{'cmd'} =~ s/\${EXEEXT:=}/.exe/g; + $cmd{'cmd'} =~ s/\${EXEEXT}/.exe/g; + $cmd{'cmd'} =~ s/\$EXEEXT/.exe/g; } - - # cleanup the command line - if($OS eq "WIN"){ - $cmd{'cmd'} =~ s/\${EXEEXT:=}/.exe/g; - $cmd{'cmd'} =~ s/\${EXEEXT}/.exe/g; - $cmd{'cmd'} =~ s/\$EXEEXT/.exe/g; - } - else{ - $cmd{'cmd'} =~ s/\${EXEEXT:=}//g; - } - $cmd{'cmd'} =~ s/\${bindir:=}/$bindir/g; - $cmd{'cmd'} =~ s/\${srcdir:=}/$srcdir/g; - $cmd{'cmd'} =~ s/\${bindir:=.}/$bindir/g; - $cmd{'cmd'} =~ s/\${srcdir:=.}/$srcdir/g; - $cmd{'cmd'} =~ s/\${bindir}/$bindir/g; - $cmd{'cmd'} =~ s/\${srcdir}/$srcdir/g; - $cmd{'cmd'} =~ s|^\./||g; -# $cmd{'cmd'} =~ s|tesh|tesh.pl|g; - $cmd{'cmd'} =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g; - $cmd{'cmd'} .= " $opts{'cfg'}" if (defined($opts{'cfg'}) && length($opts{'cfg'})); - - print "[$cmd{'file'}:$cmd{'line'}] $cmd{'cmd'}\n"; - - ### - # exec the command line - ### - $pid = open3(\*IN, \*OUT, \*OUT, $cmd{'cmd'} ); - - # if timeout specified, fork and kill executing child at the end of timeout - if ($timeout){ - $forked = fork(); - die "fork() failed: $!" unless defined $forked; - if ( $forked == 0 ) { # child - sleep $timeout; - kill(9, $pid); - exit; - } + else{ + $cmd{'cmd'} =~ s/\${EXEEXT:=}//g; + } + $cmd{'cmd'} =~ s/\${bindir:=}/$bindir/g; + $cmd{'cmd'} =~ s/\${srcdir:=}/$srcdir/g; + $cmd{'cmd'} =~ s/\${bindir:=.}/$bindir/g; + $cmd{'cmd'} =~ s/\${srcdir:=.}/$srcdir/g; + $cmd{'cmd'} =~ s/\${bindir}/$bindir/g; + $cmd{'cmd'} =~ s/\${srcdir}/$srcdir/g; +# $cmd{'cmd'} =~ s|^\./||g; +# $cmd{'cmd'} =~ s|tesh|tesh.pl|g; + $cmd{'cmd'} =~ s/\(%i:%P@%h\)/\\\(%i:%P@%h\\\)/g; + $cmd{'cmd'} .= " $opts{'cfg'}" if (defined($opts{'cfg'}) && length($opts{'cfg'})); + + print "[$tesh_name:$cmd{'line'}] $cmd{'cmd'}\n" ; + + ### + # exec the command line + ### + $pid = open3(\*CHILD_IN, \*OUT, \*OUT, $cmd{'cmd'} ); + + # push all provided input to executing child + map { print CHILD_IN "$_\n" } @{$cmd{'in'}}; + close CHILD_IN; + + # if timeout specified, fork and kill executing child at the end of timeout + if (defined($cmd{'timeout'}) or defined($opts{'timeout'})){ + $time_to_wait= defined($cmd{'timeout'}) ? $cmd{'timeout'} : $opts{'timeout'}; + $forked = fork(); + $timeout=-1; + die "fork() failed: $!" unless defined $forked; + if ( $forked == 0 ) { # child + sleep $time_to_wait; + kill(9, $pid); + exit $time_to_wait; } + } - # push all provided input to executing child - map { print IN "$_\n" } $cmd{'in'}; - close IN; - # pop all output from executing child - my @got; - while(defined(my $got=)) { - $got =~ s/\r//g; - $got =~ s/^( )*//g; - chomp $got; + # pop all output from executing child + my @got; + while(defined(my $got=)) { + $got =~ s/\r//g; + $got =~ s/^( )*//g; + chomp $got; $got=trim($got); - if( $got ne ""){ + if( $got ne ""){ + if (!($enable_coverage and $got=~ /^profiling:/)){ push @got, "$got"; - } - } - close OUT; + } + } + } + close OUT; - if ($sort){ - sub mysort{ - $a cmp $b - } - use sort qw(defaults _quicksort); # force quicksort - @got = sort mysort @got; - #also resort the other one, as perl sort is not the same as the C one used to generate teshes + if ($cmd{'sort'}){ + sub mysort{ + $a cmp $b + } + use sort qw(defaults _quicksort); # force quicksort + @got = sort mysort @got; + #also resort the other one, as perl sort is not the same as the C one used to generate teshes + if(defined($cmd{'out'})){ @{$cmd{'out'}}=sort mysort @{$cmd{'out'}}; } + } - # Cleanup the executing child, and kill the timeouter brother on need - $cmd{'return'} = 0 unless defined($cmd{'return'}); - my $wantret = "returned code ".(defined($cmd{'return'})? $cmd{'return'} : 0); - waitpid ($pid, 0); - my $gotret = exit_status($?); - if($gotret ne $wantret) { - my $msg = "Test suite `$cmd{'file'}': NOK (<$cmd{'file'}:$cmd{'line'}> $gotret)\n". - "Output of <$cmd{'file'}:$cmd{'line'}> so far:\n"; - map {$msg .= "|| $_\n"} @got; - print STDERR "$msg"; - exit(1); + # Cleanup the executing child, and kill the timeouter brother on need + $cmd{'return'} = 0 unless defined($cmd{'return'}); + my $wantret; + if(defined($cmd{'expect'}) and ($cmd{'expect'} ne "")){ + $wantret = "got signal $cmd{'expect'}"; + }else{ + $wantret = "returned code ".(defined($cmd{'return'})? $cmd{'return'} : 0); + $exitcode= 41; + } + my $gotret; + waitpid ($pid, 0); + $gotret = exit_status($?); + #Did we timeout ? If yes, handle it. If not, kill the forked process. + + if($timeout==-1 and $gotret eq "got signal SIGKILL"){ + $gotret="return code 0"; + $timeout=1; + $gotret= "timeout after $time_to_wait sec"; + $error=1; + $exitcode=3; + print STDERR "<$cmd{'file'}:$cmd{'line'}> timeouted. Kill the process.\n"; + }else{ + $timeout=0; + } + if($gotret ne $wantret) { + $error=1; + my $msg = "Test suite `$cmd{'file'}': NOK (<$cmd{'file'}:$cmd{'line'}> $gotret)\n"; + if ($timeout!=1) { + $msg=$msg."Output of <$cmd{'file'}:$cmd{'line'}> so far:\n"; } - if($timeout){kill(9, $forked);$timeout=0;} - $timeout = 0; - - ### - # Check the result of execution - ### - my $diff = build_diff(\@{$cmd{'out'}}, \@got); - if (length $diff) { - print color("red")."[TESH/CRITICAL$$] Output mismatch\n"; - map { print "[TESH/CRITICAL] $_\n" } split(/\n/,$diff); - print color("reset"); - die "Tesh failed\n"; + map {$msg .= "|| $_\n"} @got; + if(!@got) { + if($timeout==1){ + print STDERR "<$cmd{'file'}:$cmd{'line'}> No output before timeout\n"; + }else{ + $msg .= "||\n"; + } } + $timeout = 0; + print STDERR "$msg"; + } + + + ### + # Check the result of execution + ### + my $diff; + if (!defined($cmd{'output ignore'})){ + $diff = build_diff(\@{$cmd{'out'}}, \@got); + }else{ + print "(ignoring the output of <$cmd{'file'}:$cmd{'line'}> as requested)\n" + } + if (length $diff) { + print "Output of <$cmd{'file'}:$cmd{'line'}> mismatch:\n"; + map { print "$_\n" } split(/\n/,$diff); + + print "Test suite `$cmd{'file'}': NOK (<$cmd{'file'}:$cmd{'line'}> output mismatch)\n"; + $error=1; + $exitcode=2; + } } sub mkfile_cmd { - my %cmd = %{$_[0]}; - my $file = $cmd{'arg'}; - print "[Tesh/INFO] mkfile $file\n"; - - die "[TESH/CRITICAL] no input provided to mkfile\n" unless defined($cmd{'in'}) && scalar @{$cmd{'in'}}; - unlink($file); - open(FILE,">$file") or die "[Tesh/CRITICAL] Unable to create file $file: $!\n"; - print FILE join("\n", @{$cmd{'in'}}); - print FILE "\n" if (scalar @{$cmd{'in'}} > 0); - close(FILE); + my %cmd = %{$_[0]}; + my $file = $cmd{'arg'}; + print "[Tesh/INFO] mkfile $file\n"; + + die "[TESH/CRITICAL] no input provided to mkfile\n" unless defined($cmd{'in'}) && scalar @{$cmd{'in'}}; + unlink($file); + open(FILE,">$file") or die "[Tesh/CRITICAL] Unable to create file $file: $!\n"; + print FILE join("\n", @{$cmd{'in'}}); + print FILE "\n" if (scalar @{$cmd{'in'}} > 0); + close(FILE); } # parse tesh file -print "Test suite $tesh_file\n"; -open TESH_FILE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file $!\n"; +#my $teshfile=$tesh_file; +#$teshfile=~ s{\.[^.]+$}{}; +unless($tesh_file eq "(stdin)"){ + open TESH_FILE, $tesh_file or die "[Tesh/CRITICAL] Unable to open $tesh_file $!\n"; +} my %cmd; # everything about the next command to run my $line_num=0; -LINE: while (defined(my $line=)) { +my $finished =0; +LINE: while (not $finished and not $error) { + my $line; + + + if ($tesh_file ne "(stdin)" and !defined($line=)){ + $finished=1; + next LINE; + }elsif ($tesh_file eq "(stdin)" and !defined($line=<>)){ + $finished=1; + next LINE; + } + + + $line_num++; + chomp $line; + print "[TESH/debug] $line_num: $line\n" if $opts{'debug'}; + my $next; + # deal with line continuations + while ($line =~ /^(.*?)\\$/) { + $next=; + die "[TESH/CRITICAL] Continued line at end of file\n" + unless defined($next); $line_num++; - chomp $line; - print "[TESH/debug] $line_num: $line\n" if $opts{'debug'}; - - # deal with line continuations - while ($line =~ /^(.*?)\\$/) { - my $next=; - die "[TESH/CRITICAL] Continued line at end of file\n" - unless defined($next); - chomp $next; - print "[TESH/debug] $line_num: $next\n" if $opts{'debug'}; - $line = $1.$next; + chomp $next; + print "[TESH/debug] $line_num: $next\n" if $opts{'debug'}; + $line = $1.$next; + } + + # Push delayed commands on empty lines + unless ($line =~ m/^(.).(.*)$/) { + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - - # Push delayed commands on empty lines - unless ($line =~ m/^(..)(.*)$/) { - if (defined($cmd{'cmd'})) { - exec_cmd(\%cmd); - %cmd = (); - } - next LINE; - } + next LINE; + } - my ($cmd,$arg) = ($1,$2); - $arg =~ s/\r//g; - - # handle the commands - if ($cmd =~ /^#/) { #comment - } elsif ($cmd eq '> '){ #expected result line - print "[TESH/debug] push expected result\n" if $opts{'debug'}; - $arg=trim($arg); - if($arg ne ""){ - push @{$cmd{'out'}}, $arg; + my ($cmd,$arg) = ($1,$2); + $arg =~ s/\r//g; + $arg =~ s/\\\\/\\/g; + # handle the commands + if ($cmd =~ /^#/) { #comment + } elsif ($cmd eq '>'){ #expected result line + print "[TESH/debug] push expected result\n" if $opts{'debug'}; + $arg=trim($arg); + if($arg ne ""){ + push @{$cmd{'out'}}, $arg; + } + + } elsif ($cmd eq '<') { # provided input + print "[TESH/debug] push provided input\n" if $opts{'debug'}; + push @{$cmd{'in'}}, $arg; + + } elsif ($cmd eq 'p') { # comment + print "[$tesh_name:$line_num] $arg\n"; + + } elsif ($cmd eq '$') { # Command + # if we have something buffered, run it now + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); + } + if ($arg =~ /^\s*mkfile /){ # "mkfile" command line + die "[TESH/CRITICAL] Output expected from mkfile command!\n" if scalar @{cmd{'out'}}; + + $cmd{'arg'} = $arg; + $cmd{'arg'} =~ s/\s*mkfile //; + mkfile_cmd(\%cmd); + %cmd = (); + + } elsif ($arg =~ /^\s*cd /) { + die "[TESH/CRITICAL] Input provided to cd command!\n" if scalar @{cmd{'in'}}; + die "[TESH/CRITICAL] Output expected from cd command!\n" if scalar @{cmd{'out'}}; + + $arg =~ s/^ *cd //; + cd_cmd("",$arg); + %cmd = (); + + } else { # regular command + $cmd{'cmd'} = $arg; + $cmd{'file'} = $tesh_file; + $cmd{'line'} = $line_num; } + } + elsif($cmd eq '&'){ # parallel command line - } elsif ($cmd eq '< ') { # provided input - print "[TESH/debug] push provided input\n" if $opts{'debug'}; - push @{$cmd{'in'}}, $arg; - - } elsif ($cmd eq 'p ') { # comment - print "[Tesh/INFO] $arg\n"; - - } elsif ($cmd eq '$ ') { # Command - # if we have something buffered, run it now - if (defined($cmd{'cmd'})) { - exec_cmd(\%cmd); - %cmd = (); - } - if ($arg =~ /^ *mkfile /){ # "mkfile" command line - die "[TESH/CRITICAL] Output expected from mkfile command!\n" if scalar @{cmd{'out'}}; - - $cmd{'arg'} = $arg; - $cmd{'arg'} =~ s/ *mkfile //; - mkfile_cmd(\%cmd); - %cmd = (); - - } elsif ($arg =~ /^ *cd /) { - die "[TESH/CRITICAL] Input provided to cd command!\n" if scalar @{cmd{'in'}}; - die "[TESH/CRITICAL] Output expected from cd command!\n" if scalar @{cmd{'out'}}; - - $arg =~ s/^ *cd //; - cd_cmd("",$arg); - %cmd = (); - - } else { # regular command - $cmd{'cmd'} = $arg; - $cmd{'file'} = $tesh_file; - $cmd{'line'} = $line_num; - } + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($cmd eq '& '){ # parallel command line - $cmd{'background'} = 1; - $cmd{'cmd'} = $arg; - } - elsif($line =~ /^! output sort/){ #output sort - $sort=1; - $cmd{'sort'} = 1; + $cmd{'background'} = 1; + $cmd{'cmd'} = $arg; + $cmd{'file'} = $tesh_file; + $cmd{'line'} = $line_num; + } + elsif($line =~ /^!\s*output sort/){ #output sort + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! output ignore/){ #output ignore - $cmd{'output ignore'} = 1; + $cmd{'sort'} = 1; + } + elsif($line =~ /^!\s*output ignore/){ #output ignore + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! expect signal SIGABRT$/) {#expect signal SIGABRT - $cmd{'expect'} = "SIGABRT"; + $cmd{'output ignore'} = 1; + } + elsif($line =~ /^!\s*expect signal (\w*)$/) {#expect signal SIGABRT + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! expect return/){ #expect return - $line =~ s/^! expect return //g; - $line =~ s/\r//g; - $cmd{'return'} = $line; + $cmd{'expect'} = "$1"; + } + elsif($line =~ /^!\s*expect return/){ #expect return + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! setenv/){ #setenv - $line =~ s/^! setenv //g; - $line =~ s/\r//g; - setenv_cmd($line); + $line =~ s/^! expect return //g; + $line =~ s/\r//g; + $cmd{'return'} = $line; + } + elsif($line =~ /^!\s*setenv/){ #setenv + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! include/){ #output sort - print color("red"), "[Tesh/CRITICAL] need include"; - print color("reset"), "\n"; - die; + $line =~ s/^! setenv //g; + $line =~ s/\r//g; + setenv_cmd($line); + } + elsif($line =~ /^!\s*include/){ #output sort + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } - elsif($line =~ /^! timeout/){ #timeout - $line =~ s/^! timeout //; - $line =~ s/\r//g; - $cmd{'timeout'} = $line; - } else { - die "[TESH/CRITICAL] parse error: $line\n"; + print color("red"), "[Tesh/CRITICAL] need include"; + print color("reset"), "\n"; + die; + } + elsif($line =~ /^!\s*timeout/){ #timeout + if (defined($cmd{'cmd'})) { + exec_cmd(\%cmd); + %cmd = (); } + $line =~ s/^! timeout //; + $line =~ s/\r//g; + $cmd{'timeout'} = $line; + } else { + die "[TESH/CRITICAL] parse error: $line\n"; + } } + + # Deal with last command if (defined($cmd{'cmd'})) { - exec_cmd(\%cmd); - %cmd = (); + exec_cmd(\%cmd); + %cmd = (); +} + + +if($forked){ + kill(9, $forked); + $timeout=0; +} + +if($error !=0){ + exit $exitcode; +}elsif($tesh_file eq "(stdin)"){ + print "Test suite from stdin OK\n"; +}else{ + print "Test suite `$tesh_name' OK\n"; } #my (@a,@b); @@ -445,32 +582,32 @@ use lib "@CMAKE_BINARY_DIR@/bin" ; use Diff qw(diff); # postpone a bit to have time to change INC sub build_diff { - my $res; - my $diff = Diff->new(@_); - - $diff->Base( 1 ); # Return line numbers, not indices - my $chunk_count = $diff->Next(-1); # Compute the amount of chuncks - return "" if ($chunk_count == 1 && $diff->Same()); - $diff->Reset(); - while( $diff->Next() ) { - my @same = $diff->Same(); - if ($diff->Same() ) { - if ($diff->Next(0) > 1) { # not first chunk: print 2 first lines - $res .= ' '.$same[0]."\n" ; - $res .= ' '.$same[1]."\n" if (scalar @same>1); - } - $res .= "...\n" if (scalar @same>2); -# $res .= $diff->Next(0)."/$chunk_count\n"; - if ($diff->Next(0) < $chunk_count) { # not last chunk: print 2 last lines - $res .= ' '.$same[scalar @same -2]."\n" if (scalar @same>1); - $res .= ' '.$same[scalar @same -1]."\n"; - } - } - next if $diff->Same(); - map { $res .= "- $_\n" } $diff->Items(1); - map { $res .= "+ $_\n" } $diff->Items(2); - } - return $res; + my $res; + my $diff = Diff->new(@_); + + $diff->Base( 1 ); # Return line numbers, not indices + my $chunk_count = $diff->Next(-1); # Compute the amount of chuncks + return "" if ($chunk_count == 1 && $diff->Same()); + $diff->Reset(); + while( $diff->Next() ) { + my @same = $diff->Same(); + if ($diff->Same() ) { + if ($diff->Next(0) > 1) { # not first chunk: print 2 first lines + $res .= ' '.$same[0]."\n" ; + $res .= ' '.$same[1]."\n" if (scalar @same>1); + } + $res .= "...\n" if (scalar @same>2); +# $res .= $diff->Next(0)."/$chunk_count\n"; + if ($diff->Next(0) < $chunk_count) { # not last chunk: print 2 last lines + $res .= ' '.$same[scalar @same -2]."\n" if (scalar @same>1); + $res .= ' '.$same[scalar @same -1]."\n"; + } + } + next if $diff->Same(); + map { $res .= "- $_\n" } $diff->Items(1); + map { $res .= "+ $_\n" } $diff->Items(2); + } + return $res; } diff --git a/examples/msg/mc/bugged1_liveness.c b/examples/msg/mc/bugged1_liveness.c index bd59651aaa..b6949dda0c 100644 --- a/examples/msg/mc/bugged1_liveness.c +++ b/examples/msg/mc/bugged1_liveness.c @@ -51,7 +51,7 @@ int coordinator(int argc, char *argv[]) } else { if (!xbt_dynar_is_empty(requests)) { XBT_INFO("CS release. Grant to queued requests (queue size: %lu)", xbt_dynar_length(requests)); - xbt_dynar_pop(requests, &req); + xbt_dynar_shift(requests, &req); if(strcmp(req, "1") != 0){ MSG_task_send(MSG_task_create("grant", 0, 1000, NULL), req); }else{ diff --git a/examples/msg/mc/bugged1_liveness.tesh b/examples/msg/mc/bugged1_liveness.tesh index d3a29d7c8b..3413fbb5bb 100644 --- a/examples/msg/mc/bugged1_liveness.tesh +++ b/examples/msg/mc/bugged1_liveness.tesh @@ -15,7 +15,7 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (3:client@Fafard) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (0:@) Pair 22 already reached (equal to pair 10) ! +> [ 0.000000] (0:@) Pair 21 already reached (equal to pair 9) ! > [ 0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* > [ 0.000000] (0:@) | ACCEPTANCE CYCLE | > [ 0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* @@ -40,10 +40,10 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (0:@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) (54) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) Expanded pairs = 22 -> [ 0.000000] (0:@) Visited pairs = 22 -> [ 0.000000] (0:@) Executed transitions = 21 +> [ 0.000000] (0:@) Expanded pairs = 21 +> [ 0.000000] (0:@) Visited pairs = 21 +> [ 0.000000] (0:@) Executed transitions = 20 + diff --git a/examples/msg/mc/bugged1_liveness_visited.tesh b/examples/msg/mc/bugged1_liveness_visited.tesh index 932946f1ef..49d40fc57b 100644 --- a/examples/msg/mc/bugged1_liveness_visited.tesh +++ b/examples/msg/mc/bugged1_liveness_visited.tesh @@ -25,137 +25,55 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it > [ 0.000000] (3:client@Fafard) Propositions changed : r=1, cs=0 > [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) > [ 0.000000] (2:client@Boivin) Ask the request > [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly > [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (0:@) Pair 86 already reached (equal to pair 74) ! +> [ 0.000000] (0:@) Pair 57 already reached (equal to pair 45) ! > [ 0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* > [ 0.000000] (0:@) | ACCEPTANCE CYCLE | > [ 0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* @@ -174,23 +92,11 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) (54) > [ 0.000000] (0:@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (56) +> [ 0.000000] (0:@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) (54) +> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) (62) @@ -205,23 +111,11 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) -> [ 0.000000] (0:@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) +> [ 0.000000] (0:@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) (62) +> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) @@ -234,7 +128,6 @@ $ ${bindir:=.}/bugged1_liveness ${bindir:=.}/../msg_platform.xml ${bindir:=.}/de > [ 0.000000] (0:@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) (56) > [ 0.000000] (0:@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) (62) > [ 0.000000] (0:@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) (54) -> [ 0.000000] (0:@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) (62) -> [ 0.000000] (0:@) Expanded pairs = 86 -> [ 0.000000] (0:@) Visited pairs = 461 -> [ 0.000000] (0:@) Executed transitions = 460 +> [ 0.000000] (0:@) Expanded pairs = 57 +> [ 0.000000] (0:@) Visited pairs = 208 +> [ 0.000000] (0:@) Executed transitions = 207 \ No newline at end of file diff --git a/examples/msg/mc/centralized_mutex.c b/examples/msg/mc/centralized_mutex.c index 64008b4e09..3403c88286 100644 --- a/examples/msg/mc/centralized_mutex.c +++ b/examples/msg/mc/centralized_mutex.c @@ -45,7 +45,7 @@ int coordinator(int argc, char *argv[]) XBT_INFO("CS release. Grant to queued requests (queue size: %lu)", xbt_dynar_length(requests)); char *req; - xbt_dynar_pop(requests, &req); + xbt_dynar_shift(requests, &req); MSG_task_send(MSG_task_create("grant", 0, 1000, NULL), req); todo--; } else { // nobody wants it diff --git a/examples/simdag/dot/dot_test.c b/examples/simdag/dot/dot_test.c index 4456c2f1f1..e5863347a9 100644 --- a/examples/simdag/dot/dot_test.c +++ b/examples/simdag/dot/dot_test.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) /* load the DOT file */ dot = SD_dotload(argv[2]); if(dot == NULL){ - XBT_CRITICAL("No dot load may be you have a cycle in your graph"); + XBT_CRITICAL("No dot loaded. Do you have a cycle in your graph?"); SD_exit(); exit(2); } diff --git a/examples/smpi/mc/bugged1_liveness.c b/examples/smpi/mc/bugged1_liveness.c index 4b5b067d3b..eab2b55852 100644 --- a/examples/smpi/mc/bugged1_liveness.c +++ b/examples/smpi/mc/bugged1_liveness.c @@ -65,7 +65,7 @@ int main(int argc, char **argv){ }else{ if(!xbt_dynar_is_empty(requests)){ printf("CS release. Grant to queued requests (queue size: %lu)", xbt_dynar_length(requests)); - xbt_dynar_pop(requests, &recv_buff); + xbt_dynar_shift(requests, &recv_buff); if(recv_buff != 1){ MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD); CS_used = 1; diff --git a/include/smpi/smpi.h b/include/smpi/smpi.h index eaf6fac5e6..710e5da2a1 100644 --- a/include/smpi/smpi.h +++ b/include/smpi/smpi.h @@ -165,12 +165,12 @@ typedef struct { int count; } MPI_Status; -#define MPI_STATUS_IGNORE NULL -#define MPI_STATUSES_IGNORE NULL +#define MPI_STATUS_IGNORE ((MPI_Status*)NULL) +#define MPI_STATUSES_IGNORE ((MPI_Status*)NULL) #define MPI_FORTRAN_STATUS_IGNORE -1 #define MPI_FORTRAN_STATUSES_IGNORE -1 -#define MPI_DATATYPE_NULL NULL +#define MPI_DATATYPE_NULL ((MPI_Datatype)NULL) XBT_PUBLIC_DATA( MPI_Datatype ) MPI_CHAR; XBT_PUBLIC_DATA( MPI_Datatype ) MPI_SHORT; XBT_PUBLIC_DATA( MPI_Datatype ) MPI_INT; @@ -223,7 +223,7 @@ typedef void MPI_User_function(void *invec, void *inoutvec, int *len, struct s_smpi_mpi_op; typedef struct s_smpi_mpi_op *MPI_Op; -#define MPI_OP_NULL NULL +#define MPI_OP_NULL ((MPI_Op)NULL) XBT_PUBLIC_DATA( MPI_Op ) MPI_MAX; XBT_PUBLIC_DATA( MPI_Op ) MPI_MIN; XBT_PUBLIC_DATA( MPI_Op ) MPI_MAXLOC; @@ -240,14 +240,14 @@ XBT_PUBLIC_DATA( MPI_Op ) MPI_BXOR; struct s_smpi_mpi_group; typedef struct s_smpi_mpi_group *MPI_Group; -#define MPI_GROUP_NULL NULL +#define MPI_GROUP_NULL ((MPI_Group)NULL) XBT_PUBLIC_DATA( MPI_Group ) MPI_GROUP_EMPTY; struct s_smpi_mpi_communicator; typedef struct s_smpi_mpi_communicator *MPI_Comm; -#define MPI_COMM_NULL NULL +#define MPI_COMM_NULL ((MPI_Comm)NULL) XBT_PUBLIC_DATA( MPI_Comm ) MPI_COMM_WORLD; XBT_PUBLIC_DATA( int ) MPI_UNIVERSE_SIZE; #define MPI_COMM_SELF smpi_process_comm_self() @@ -255,7 +255,7 @@ XBT_PUBLIC_DATA( int ) MPI_UNIVERSE_SIZE; struct s_smpi_mpi_request; typedef struct s_smpi_mpi_request *MPI_Request; -#define MPI_REQUEST_NULL NULL +#define MPI_REQUEST_NULL ((MPI_Request)NULL) #define MPI_FORTRAN_REQUEST_NULL -1 MPI_CALL(XBT_PUBLIC(int), MPI_Init, (int *argc, char ***argv)); diff --git a/include/xbt/mmalloc.h b/include/xbt/mmalloc.h index 0e6485256a..9708a76401 100644 --- a/include/xbt/mmalloc.h +++ b/include/xbt/mmalloc.h @@ -56,7 +56,7 @@ XBT_PUBLIC( xbt_mheap_t ) mmalloc_get_default_md(void); void mmalloc_set_current_heap(xbt_mheap_t new_heap); xbt_mheap_t mmalloc_get_current_heap(void); -int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2); +int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dict_t all_types, xbt_dict_t other_types); int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2); int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2); int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type, int pointer_level); diff --git a/src/mc/mc_compare.c b/src/mc/mc_compare.c index b58023327b..7f2ea631c3 100644 --- a/src/mc/mc_compare.c +++ b/src/mc/mc_compare.c @@ -308,6 +308,7 @@ static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack current_var2 = (local_variable_t)xbt_dynar_get_as(stack2->local_variables, cursor, local_variable_t); if(strcmp(current_var1->name, current_var2->name) != 0 || strcmp(current_var1->frame, current_var2->frame) != 0 || current_var1->ip != current_var2->ip){ xbt_dynar_free(&compared_pointers); + XBT_VERB("Different name of variable (%s - %s) or frame (%s - %s) or ip (%lu - %lu)", current_var1->name, current_var2->name, current_var1->frame, current_var2->frame, current_var1->ip, current_var2->ip); return 1; } offset1 = (char *)current_var1->address - (char *)std_heap; @@ -340,6 +341,11 @@ int snapshot_compare(void *state1, void *state2){ s2 = ((mc_pair_t)state2)->graph_state->system_state; num1 = ((mc_pair_t)state1)->num; num2 = ((mc_pair_t)state2)->num; + /* Firstly compare automaton state */ + /*if(xbt_automaton_state_compare(((mc_pair_t)state1)->automaton_state, ((mc_pair_t)state2)->automaton_state) != 0) + return 1; + if(xbt_automaton_propositional_symbols_compare_value(((mc_pair_t)state1)->atomic_propositions, ((mc_pair_t)state2)->atomic_propositions) != 0) + return 1;*/ }else{ /* Safety MC */ s1 = ((mc_visited_state_t)state1)->system_state; s2 = ((mc_visited_state_t)state2)->system_state; @@ -580,7 +586,7 @@ int snapshot_compare(void *state1, void *state2){ #endif /* Compare heap */ - if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data) > 0){ + if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data, mc_variables_type_libsimgrid, mc_variables_type_binary) > 0){ #ifdef MC_DEBUG xbt_os_walltimer_stop(timer); diff --git a/src/mc/mc_dpor.c b/src/mc/mc_dpor.c index 4209fac184..643acf88dc 100644 --- a/src/mc/mc_dpor.c +++ b/src/mc/mc_dpor.c @@ -118,13 +118,14 @@ static int is_visited_state(){ }else{ int min = -1, max = -1, index; - int res; + //int res; mc_visited_state_t state_test; + int cursor; index = get_search_interval(visited_states, new_state, &min, &max); if(min != -1 && max != -1){ - res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state); + /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state); if(res != -1){ state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t); if(state_test->other_num == -1) @@ -140,7 +141,27 @@ static int is_visited_state(){ if(!raw_mem_set) MC_UNSET_RAW_MEM; return new_state->other_num; - } + }*/ + cursor = min; + while(cursor <= max){ + state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t); + if(snapshot_compare(state_test, new_state) == 0){ + if(state_test->other_num == -1) + new_state->other_num = state_test->num; + else + new_state->other_num = state_test->other_num; + if(dot_output == NULL) + XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num); + else + XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num); + xbt_dynar_remove_at(visited_states, cursor, NULL); + xbt_dynar_insert_at(visited_states, cursor, &new_state); + if(!raw_mem_set) + MC_UNSET_RAW_MEM; + return new_state->other_num; + } + cursor++; + } xbt_dynar_insert_at(visited_states, min, &new_state); }else{ state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, index, mc_visited_state_t); @@ -203,6 +224,9 @@ void MC_dpor_init() /* Wait for requests (schedules processes) */ MC_wait_for_requests(); + MC_ignore_heap(simix_global->process_to_run->data, 0); + MC_ignore_heap(simix_global->process_that_ran->data, 0); + MC_SET_RAW_MEM; /* Get an enabled process and insert it in the interleave set of the initial state */ diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index 558fca058b..2fba00d1a6 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -1757,11 +1757,19 @@ void MC_init(){ MC_ignore_global_variable("mc_snapshot_comparison_time"); MC_ignore_global_variable("mc_time"); MC_ignore_global_variable("smpi_current_rank"); - MC_ignore_global_variable("smx_current_context_serial"); - MC_ignore_global_variable("smx_current_context_key"); - MC_ignore_global_variable("sysv_maestro_context"); MC_ignore_global_variable("counter"); /* Static variable used for tracing */ - + MC_ignore_global_variable("maestro_stack_start"); + MC_ignore_global_variable("maestro_stack_end"); + + MC_ignore_heap(&(simix_global->process_to_run), sizeof(simix_global->process_to_run)); + MC_ignore_heap(&(simix_global->process_that_ran), sizeof(simix_global->process_that_ran)); + MC_ignore_heap(simix_global->process_to_run, sizeof(*(simix_global->process_to_run))); + MC_ignore_heap(simix_global->process_that_ran, sizeof(*(simix_global->process_that_ran))); + + smx_process_t process; + xbt_swag_foreach(process, simix_global->process_list){ + MC_ignore_heap(&(process->process_hookup), sizeof(process->process_hookup)); + } if(raw_mem_set) MC_SET_RAW_MEM; diff --git a/src/mc/mc_liveness.c b/src/mc/mc_liveness.c index 6f977cdf88..2007c64952 100644 --- a/src/mc/mc_liveness.c +++ b/src/mc/mc_liveness.c @@ -117,17 +117,32 @@ static int is_reached_acceptance_pair(mc_pair_t pair){ } int min = -1, max = -1, index; - int res; + //int res; mc_pair_t pair_test; - + int cursor; + index = get_search_interval(acceptance_pairs, pair, &min, &max); - if(min != -1 && max != -1){ /* Acceptance pair with same number of processes and same heap bytes used exists */ - res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(acceptance_pairs, min), (max-min)+1, pair); + if(min != -1 && max != -1){ // Acceptance pair with same number of processes and same heap bytes used exists + /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(acceptance_pairs, min), (max-min)+1, pair); if(res != -1){ if(!raw_mem_set) MC_UNSET_RAW_MEM; return ((mc_pair_t)xbt_dynar_get_as(acceptance_pairs, (min+res)-1, mc_pair_t))->num; + }*/ + cursor = min; + while(cursor <= max){ + pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t); + if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){ + if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){ + if(snapshot_compare(pair_test, pair) == 0){ + if(!raw_mem_set) + MC_UNSET_RAW_MEM; + return pair_test->num; + } + } + } + cursor++; } xbt_dynar_insert_at(acceptance_pairs, min, &pair); }else{ @@ -203,10 +218,15 @@ static void set_acceptance_pair_reached(mc_pair_t pair){ } } - if(bytes_used_test < current_bytes_used) - xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair); - else - xbt_dynar_insert_at(acceptance_pairs, cursor, &pair); + if(pair_test->nb_processes < pair->nb_processes){ + xbt_dynar_insert_at(acceptance_pairs, cursor+1, &pair); + }else{ + if(pair_test->heap_bytes_used < pair->heap_bytes_used) + xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair); + else + xbt_dynar_insert_at(acceptance_pairs, cursor, &pair); + } + } if(!raw_mem_set) @@ -274,13 +294,14 @@ static int is_visited_pair(mc_pair_t pair){ pair->graph_state->system_state = MC_take_snapshot(); int min = -1, max = -1, index; - int res; + //int res; mc_pair_t pair_test; + int cursor; index = get_search_interval(visited_pairs, pair, &min, &max); - if(min != -1 && max != -1){ /* Visited pair with same number of processes and same heap bytes used exists */ - res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_pairs, min), (max-min)+1, pair); + if(min != -1 && max != -1){ // Visited pair with same number of processes and same heap bytes used exists + /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_pairs, min), (max-min)+1, pair); if(res != -1){ pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, (min+res)-1, mc_pair_t); if(pair_test->other_num == -1) @@ -306,6 +327,40 @@ static int is_visited_pair(mc_pair_t pair){ if(!raw_mem_set) MC_UNSET_RAW_MEM; return pair->other_num; + }*/ + cursor = min; + while(cursor <= max){ + pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t); + if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){ + if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){ + if(snapshot_compare(pair_test, pair) == 0){ + if(pair_test->other_num == -1) + pair->other_num = pair_test->num; + else + pair->other_num = pair_test->other_num; + if(dot_output == NULL) + XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num); + else + XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num); + xbt_dynar_remove_at(visited_pairs, cursor, NULL); + xbt_dynar_insert_at(visited_pairs, cursor, &pair); + pair_test->visited_removed = 1; + if(pair_test->stack_removed && pair_test->visited_removed){ + if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){ + if(pair_test->acceptance_removed){ + MC_pair_delete(pair_test); + } + }else{ + MC_pair_delete(pair_test); + } + } + if(!raw_mem_set) + MC_UNSET_RAW_MEM; + return pair->other_num; + } + } + } + cursor++; } xbt_dynar_insert_at(visited_pairs, min, &pair); }else{ @@ -396,6 +451,9 @@ void MC_ddfs_init(void){ MC_wait_for_requests(); + MC_ignore_heap(simix_global->process_to_run->data, 0); + MC_ignore_heap(simix_global->process_that_ran->data, 0); + MC_SET_RAW_MEM; acceptance_pairs = xbt_dynar_new(sizeof(mc_pair_t), NULL); diff --git a/src/msg/msg_mailbox.c b/src/msg/msg_mailbox.c index 907ecdfbd1..83840e5c73 100644 --- a/src/msg/msg_mailbox.c +++ b/src/msg/msg_mailbox.c @@ -240,7 +240,8 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, /* Try to send it by calling SIMIX network layer */ TRY { - smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size, + smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simix call */ + comm = simcall_comm_isend(mailbox, t_simdata->message_size, t_simdata->rate, task, sizeof(void *), NULL, NULL, task, 0); #ifdef HAVE_TRACING diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index bfed0bafe9..7af670a28e 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -357,7 +357,7 @@ void SIMIX_run(void) TRACE_end(); #endif - XBT_WARN("Oops ! Deadlock or code not perfectly clean."); + XBT_CRITICAL("Oops ! Deadlock or code not perfectly clean."); SIMIX_display_process_status(); xbt_abort(); } diff --git a/src/simix/smx_synchro.c b/src/simix/smx_synchro.c index cd9645b41d..c9d14d0a46 100644 --- a/src/simix/smx_synchro.c +++ b/src/simix/smx_synchro.c @@ -466,7 +466,7 @@ void SIMIX_sem_release(smx_sem_t sem) } /** @brief Returns true if acquiring this semaphore would block */ -XBT_INLINE int SIMIX_sem_would_block(smx_sem_t sem) +int SIMIX_sem_would_block(smx_sem_t sem) { XBT_IN("(%p)",sem); XBT_OUT(); diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index bcc6ba83c1..a4453a8cbd 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -760,9 +760,11 @@ void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate, if (MC_is_active()) { /* the model-checker wants two separate simcalls */ - smx_action_t comm = simcall_comm_isend(rdv, task_size, rate, + smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */ + comm = simcall_comm_isend(rdv, task_size, rate, src_buff, src_buff_size, match_fun, NULL, data, 0); simcall_comm_wait(comm, timeout); + comm = NULL; } else { simcall_BODY_comm_send(rdv, task_size, rate, src_buff, src_buff_size, @@ -801,9 +803,11 @@ void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size, if (MC_is_active()) { /* the model-checker wants two separate simcalls */ - smx_action_t comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size, + smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */ + comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size, match_fun, data); simcall_comm_wait(comm, timeout); + comm = NULL; } else { simcall_BODY_comm_recv(rdv, dst_buff, dst_buff_size, diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index bb00f04147..eed7b81095 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -187,7 +187,7 @@ static MPI_Request build_request(void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags) { - MPI_Request request; + MPI_Request request = NULL; void *old_buf = NULL; @@ -219,6 +219,7 @@ static MPI_Request build_request(void *buf, int count, request->flags = flags; request->detached = 0; request->detached_sender = NULL; + request->real_src = 0; request->truncated = 0; request->real_size = 0; @@ -284,9 +285,9 @@ static void smpi_mpi_request_free_voidp(void* request) MPI_Request smpi_mpi_send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, PERSISTENT | SEND | PREPARED); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, PERSISTENT | SEND | PREPARED); request->refcount++; return request; } @@ -294,9 +295,9 @@ MPI_Request smpi_mpi_send_init(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_ssend_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, PERSISTENT | SSEND | SEND | PREPARED); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, PERSISTENT | SSEND | SEND | PREPARED); request->refcount++; return request; } @@ -304,9 +305,9 @@ MPI_Request smpi_mpi_ssend_init(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, PERSISTENT | RECV | PREPARED); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, PERSISTENT | RECV | PREPARED); request->refcount++; return request; } @@ -315,10 +316,9 @@ void smpi_mpi_start(MPI_Request request) { smx_rdv_t mailbox; - xbt_assert(!request->action, - "Cannot (re)start a non-finished communication"); - if(request->flags & PREPARED)request->flags &= ~PREPARED; - if(request->flags & RECV) { + xbt_assert(!request->action, "Cannot (re)start a non-finished communication"); + request->flags &= ~PREPARED; + if (request->flags & RECV) { print_request("New recv", request); //FIXME: if receive is posted with a large size, but send is smaller, mailboxes may not match ! if (request->size < sg_cfg_get_int("smpi/async_small_thres")) @@ -442,20 +442,18 @@ void smpi_mpi_request_free(MPI_Request * request) MPI_Request smpi_isend_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf , count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | ISEND | SEND | PREPARED); - + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf , count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SEND | PREPARED); return request; } MPI_Request smpi_mpi_isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM?(void*)0:buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | ISEND | SEND); - + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM?(void*)0:buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SEND); smpi_mpi_start(request); return request; } @@ -463,9 +461,9 @@ MPI_Request smpi_mpi_isend(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_mpi_issend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | ISEND | SSEND | SEND); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | ISEND | SSEND | SEND); smpi_mpi_start(request); return request; } @@ -475,19 +473,18 @@ MPI_Request smpi_mpi_issend(void *buf, int count, MPI_Datatype datatype, MPI_Request smpi_irecv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, NON_PERSISTENT | RECV | PREPARED); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, NON_PERSISTENT | RECV | PREPARED); return request; } MPI_Request smpi_mpi_irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, - comm, NON_PERSISTENT | RECV); - + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : smpi_group_index(smpi_comm_group(comm), src), smpi_process_index(), tag, + comm, NON_PERSISTENT | RECV); smpi_mpi_start(request); return request; } @@ -495,9 +492,10 @@ MPI_Request smpi_mpi_irecv(void *buf, int count, MPI_Datatype datatype, void smpi_mpi_recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status) { - MPI_Request request; + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm); smpi_mpi_wait(&request, status); + request = NULL; } @@ -505,23 +503,25 @@ void smpi_mpi_recv(void *buf, int count, MPI_Datatype datatype, int src, void smpi_mpi_send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | SEND); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | SEND); + smpi_mpi_start(request); smpi_mpi_wait(&request, MPI_STATUS_IGNORE); - + request = NULL; } void smpi_mpi_ssend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - MPI_Request request = - build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, - comm, NON_PERSISTENT | SSEND | SEND); + MPI_Request request = NULL; /* MC needs the comm to be set to NULL during the call */ + request = build_request(buf==MPI_BOTTOM ? (void*)0 : buf, count, datatype, smpi_process_index(), smpi_group_index(smpi_comm_group(comm), dst), tag, + comm, NON_PERSISTENT | SSEND | SEND); smpi_mpi_start(request); smpi_mpi_wait(&request, MPI_STATUS_IGNORE); + request = NULL; } void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, @@ -557,11 +557,10 @@ int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype) static void finish_wait(MPI_Request * request, MPI_Status * status) { MPI_Request req = *request; - if(status != MPI_STATUS_IGNORE) - smpi_empty_status(status); + smpi_empty_status(status); if(!(req->detached && req->flags & SEND) && !(req->flags & PREPARED)){ - if(status != MPI_STATUS_IGNORE) { + if(status != MPI_STATUS_IGNORE) { int src = req->src == MPI_ANY_SOURCE ? req->real_src : req->src; status->MPI_SOURCE = smpi_group_rank(smpi_comm_group(req->comm), src); status->MPI_TAG = req->tag == MPI_ANY_TAG ? req->real_tag : req->tag; @@ -576,8 +575,8 @@ static void finish_wait(MPI_Request * request, MPI_Status * status) MPI_Datatype datatype = req->old_type; if(datatype->has_subtype == 1){ - // This part handles the problem of non-contignous memory - // the unserialization at the reception + // This part handles the problem of non-contignous memory + // the unserialization at the reception s_smpi_subtype_t *subtype = datatype->substruct; if(req->flags & RECV) { subtype->unserialize(req->buf, req->old_buf, req->real_size/smpi_datatype_size(datatype) , datatype->substruct); @@ -590,13 +589,13 @@ static void finish_wait(MPI_Request * request, MPI_Status * status) } #ifdef HAVE_TRACING - if (TRACE_smpi_view_internals()) { - if(req->flags & RECV){ - int rank = smpi_process_index(); - int src_traced = (req->src == MPI_ANY_SOURCE ? req->real_src : req->src); - TRACE_smpi_recv(rank, src_traced, rank); - } + if (TRACE_smpi_view_internals()) { + if(req->flags & RECV){ + int rank = smpi_process_index(); + int src_traced = (req->src == MPI_ANY_SOURCE ? req->real_src : req->src); + TRACE_smpi_recv(rank, src_traced, rank); } + } #endif if(req->detached_sender!=NULL){ @@ -614,15 +613,15 @@ int smpi_mpi_test(MPI_Request * request, MPI_Status * status) { int flag; //assume that request is not MPI_REQUEST_NULL (filtered in PMPI_Test or smpi_mpi_testall before) - if ((*request)->action == NULL) - flag = 1; - else - flag = simcall_comm_test((*request)->action); - if(flag) { - finish_wait(request, status); - request=MPI_REQUEST_NULL; - }else{ - smpi_empty_status(status); + smpi_empty_status(status); + flag = 1; + if (!((*request)->flags & PREPARED)) { + if ((*request)->action != NULL) + flag = simcall_comm_test((*request)->action); + if (flag) { + finish_wait(request, status); + *request = MPI_REQUEST_NULL; + } } return flag; } @@ -640,7 +639,8 @@ int smpi_mpi_testany(int count, MPI_Request requests[], int *index, map = xbt_new(int, count); size = 0; for(i = 0; i < count; i++) { - if((requests[i]!=MPI_REQUEST_NULL) && requests[i]->action) { + if ((requests[i] != MPI_REQUEST_NULL) && requests[i]->action && + !(requests[i]->flags & PREPARED)) { xbt_dynar_push(comms, &requests[i]->action); map[size] = i; size++; @@ -652,6 +652,7 @@ int smpi_mpi_testany(int count, MPI_Request requests[], int *index, if(i != -1) { *index = map[i]; finish_wait(&requests[*index], status); + requests[*index] = MPI_REQUEST_NULL; flag = 1; } }else{ @@ -674,7 +675,7 @@ int smpi_mpi_testall(int count, MPI_Request requests[], int flag=1; int i; for(i=0; iflags & PREPARED)) { if (smpi_mpi_test(&requests[i], pstat)!=1){ flag=0; }else{ @@ -751,11 +752,22 @@ void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* void smpi_mpi_wait(MPI_Request * request, MPI_Status * status) { print_request("Waiting", *request); + if ((*request)->flags & PREPARED) { + smpi_empty_status(status); + return; + } + if ((*request)->action != NULL) { // this is not a detached send simcall_comm_wait((*request)->action, -1.0); } + +#ifdef HAVE_MC + if(MC_is_active()) + (*request)->action->comm.dst_data = NULL; // dangling pointer : dst_data is freed with a wait, need to set it to NULL for system state comparison +#endif + finish_wait(request, status); - request=MPI_REQUEST_NULL; + *request = MPI_REQUEST_NULL; // FIXME for a detached send, finish_wait is not called: } @@ -774,7 +786,7 @@ int smpi_mpi_waitany(int count, MPI_Request requests[], size = 0; XBT_DEBUG("Wait for one of %d", count); for(i = 0; i < count; i++) { - if(requests[i] != MPI_REQUEST_NULL) { + if (requests[i] != MPI_REQUEST_NULL && !(requests[i]->flags & PREPARED)) { if (requests[i]->action != NULL) { XBT_DEBUG("Waiting any %p ", requests[i]); xbt_dynar_push(comms, &requests[i]->action); @@ -797,6 +809,7 @@ int smpi_mpi_waitany(int count, MPI_Request requests[], if (i != -1) { index = map[i]; finish_wait(&requests[index], status); + requests[index] = MPI_REQUEST_NULL; } } xbt_free(map); @@ -819,7 +832,8 @@ int smpi_mpi_waitall(int count, MPI_Request requests[], //tag invalid requests in the set if (status != MPI_STATUSES_IGNORE) { for (c = 0; c < count; c++) { - if (requests[c] == MPI_REQUEST_NULL || requests[c]->dst == MPI_PROC_NULL) { + if (requests[c] == MPI_REQUEST_NULL || requests[c]->dst == MPI_PROC_NULL || + (requests[c]->flags & PREPARED)) { smpi_empty_status(&status[c]); } else if (requests[c]->src == MPI_PROC_NULL) { smpi_empty_status(&status[c]); diff --git a/src/smpi/smpi_pmpi.c b/src/smpi/smpi_pmpi.c index bcbe9b9fc0..f9a06a5ce4 100644 --- a/src/smpi/smpi_pmpi.c +++ b/src/smpi/smpi_pmpi.c @@ -1374,10 +1374,11 @@ int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status) int retval = 0; smpi_bench_end(); - if (request == MPI_REQUEST_NULL || flag == NULL) { + if (request == NULL || flag == NULL) { retval = MPI_ERR_ARG; } else if (*request == MPI_REQUEST_NULL) { *flag= TRUE; + smpi_empty_status(status); retval = MPI_ERR_REQUEST; } else { *flag = smpi_mpi_test(request, status); @@ -1468,6 +1469,8 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status) smpi_bench_end(); + smpi_empty_status(status); + if (request == NULL) { retval = MPI_ERR_ARG; } else if (*request == MPI_REQUEST_NULL) { @@ -1475,32 +1478,32 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status) } else { #ifdef HAVE_TRACING - int rank = request && (*request)->comm != MPI_COMM_NULL + int rank = request && (*request)->comm != MPI_COMM_NULL ? smpi_process_index() : -1; - TRACE_smpi_computing_out(rank); + TRACE_smpi_computing_out(rank); - int src_traced = (*request)->src; - int dst_traced = (*request)->dst; - MPI_Comm comm = (*request)->comm; - int is_wait_for_receive = (*request)->recv; - TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__,-1); + int src_traced = (*request)->src; + int dst_traced = (*request)->dst; + MPI_Comm comm = (*request)->comm; + int is_wait_for_receive = (*request)->recv; + TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__,-1); #endif smpi_mpi_wait(request, status); retval = MPI_SUCCESS; #ifdef HAVE_TRACING - //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE) - TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__); - if (is_wait_for_receive) { - if(src_traced==MPI_ANY_SOURCE) - src_traced = (status!=MPI_STATUS_IGNORE) ? - smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) : - src_traced; - TRACE_smpi_recv(rank, src_traced, dst_traced); - } - TRACE_smpi_computing_in(rank); + //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE) + TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__); + if (is_wait_for_receive) { + if(src_traced==MPI_ANY_SOURCE) + src_traced = (status!=MPI_STATUS_IGNORE) ? + smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) : + src_traced; + TRACE_smpi_recv(rank, src_traced, dst_traced); + } + TRACE_smpi_computing_in(rank); #endif } @@ -2324,7 +2327,7 @@ int PMPI_Type_commit(MPI_Datatype* datatype) { int retval = 0; smpi_bench_end(); - if (datatype == MPI_DATATYPE_NULL) { + if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) { retval = MPI_ERR_TYPE; } else { smpi_datatype_commit(datatype); diff --git a/src/xbt/mmalloc/mm_diff.c b/src/xbt/mmalloc/mm_diff.c index 86733e3e26..49c5968780 100644 --- a/src/xbt/mmalloc/mm_diff.c +++ b/src/xbt/mmalloc/mm_diff.c @@ -130,11 +130,14 @@ static int compare_backtrace(int b1, int f1, int b2, int f2){ /*********************************** Heap comparison ***********************************/ /***************************************************************************************/ +typedef char* type_name; + __thread void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL; __thread malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL; __thread size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0; __thread xbt_dynar_t to_ignore1 = NULL, to_ignore2 = NULL; __thread heap_area_t **equals_to1, **equals_to2; +__thread type_name **types1, **types2; /*********************************** Free functions ************************************/ @@ -194,7 +197,7 @@ static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int b return 0; } -static size_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address){ +static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address){ unsigned int cursor = 0; int start = 0; @@ -212,7 +215,7 @@ static size_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address end = cursor - 1; } - return 0; + return -1; } static int is_stack(void *address){ @@ -328,18 +331,25 @@ int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1, to_ignore2 = i2; equals_to1 = malloc(heaplimit * sizeof(heap_area_t *)); + types1 = malloc(heaplimit * sizeof(type_name *)); for(i=0; i<=heaplimit; i++){ equals_to1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t)); - for(j=0; jheapbase)); - res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); + res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0); - if(res_compare == 0){ + if(res_compare != 1){ for(k=1; k < heapinfo2[i1].busy_block.size; k++) equals_to2[i1+k][0] = new_heap_area(i1, -1); for(k=1; k < heapinfo1[i1].busy_block.size; k++) @@ -479,9 +500,9 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){ continue; } - res_compare = compare_heap_area(addr_block1, addr_block2, NULL, NULL, NULL, NULL, 0); + res_compare = compare_heap_area(addr_block1, addr_block2, NULL, all_types, other_types, NULL, 0); - if(res_compare == 0){ + if(res_compare != 1 ){ for(k=1; k < heapinfo2[i2].busy_block.size; k++) equals_to2[i2+k][0] = new_heap_area(i1, -1); for(k=1; k < heapinfo1[i1].busy_block.size; k++) @@ -526,9 +547,9 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){ addr_block2 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase)); addr_frag2 = (void*) ((char *)addr_block2 + (j1 << ((xbt_mheap_t)s_heap)->heapinfo[i1].type)); - res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); + res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0); - if(res_compare == 0) + if(res_compare != 1) equal = 1; xbt_dynar_reset(previous); @@ -555,9 +576,9 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){ addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase)); addr_frag2 = (void*) ((char *)addr_block2 + (j2 <<((xbt_mheap_t)s_heap)->heapinfo[i2].type)); - res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, NULL, NULL, NULL, 0); + res_compare = compare_heap_area(addr_frag1, addr_frag2, NULL, all_types, other_types, NULL, 0); - if(res_compare == 0){ + if(res_compare != 1){ equal = 1; xbt_dynar_reset(previous); break; @@ -688,11 +709,16 @@ static int compare_heap_area_without_type(void *real_area1, void *real_area2, vo while(i 0){ - if((ignore1 = heap_comparison_ignore_size(to_ignore1, (char *)real_area1 + i)) > 0){ + if((ignore1 = heap_comparison_ignore_size(to_ignore1, (char *)real_area1 + i)) != -1){ if((ignore2 = heap_comparison_ignore_size(to_ignore2, (char *)real_area2 + i)) == ignore1){ - i = i + ignore2; - check_ignore--; - continue; + if(ignore1 == 0){ + check_ignore--; + return 0; + }else{ + i = i + ignore2; + check_ignore--; + continue; + } } } } @@ -709,8 +735,9 @@ static int compare_heap_area_without_type(void *real_area1, void *real_area2, vo }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) && (addr_pointed2 > s_heap) && ((char *)addr_pointed2 < (char *)s_heap + STD_HEAP_SIZE)){ res_compare = compare_heap_area(addr_pointed1, addr_pointed2, previous, all_types, other_types, NULL, 0); - if(res_compare == 1) + if(res_compare == 1){ return res_compare; + } i = pointer_align + sizeof(void *); continue; }else{ @@ -737,8 +764,9 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void size_t ignore1, ignore2; - if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1)) + if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1)){ return 0; + } dw_type_t type = xbt_dict_get_or_null(all_types, type_id); dw_type_t subtype, subsubtype; @@ -750,8 +778,6 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void switch(type->type){ case e_dw_base_type: - if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1)) - return 0; if(strcmp(type->name, "char") == 0){ /* String, hence random (arbitrary ?) size */ if(real_area1 == real_area2) return -1; @@ -760,13 +786,12 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void }else{ if(area_size != -1 && type->size != area_size) return -1; - else - return (memcmp(area1, area2, type->size) != 0); + else{ + return (memcmp(area1, area2, type->size) != 0); + } } break; case e_dw_enumeration_type: - if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1)) - return 0; if(area_size != -1 && type->size != area_size) return -1; else @@ -815,7 +840,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void return 0; break; } - for(i=0; isize; i++){ + for(i=0; isize; i++){ if(switch_types) res = compare_heap_area_with_type((char *)real_area1 + (i*elm_size), (char *)real_area2 + (i*elm_size), (char *)area1 + (i*elm_size), (char *)area2 + (i*elm_size), previous, other_types, all_types, type->dw_type_id, type->size, check_ignore, pointer_level); else @@ -832,7 +857,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void }else{ pointer_level++; if(pointer_level > 1){ /* Array of pointers */ - for(i=0; i<(area_size/sizeof(void *)); i++){ + for(i=0; i<(area_size/sizeof(void *)); i++){ addr_pointed1 = *((void **)((char *)area1 + (i*sizeof(void *)))); addr_pointed2 = *((void **)((char *)area2 + (i*sizeof(void *)))); if(addr_pointed1 > s_heap && (char *)addr_pointed1 < (char*) s_heap + STD_HEAP_SIZE && addr_pointed2 > s_heap && (char *)addr_pointed2 < (char*) s_heap + STD_HEAP_SIZE) @@ -864,7 +889,7 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void } if(area_size != -1 && type->size != area_size){ if(area_size>type->size && area_size%type->size == 0){ - for(i=0; i<(area_size/type->size); i++){ + for(i=0; i<(area_size/type->size); i++){ if(switch_types) res = compare_heap_area_with_type((char *)real_area1 + (i*type->size), (char *)real_area2 + (i*type->size), (char *)area1 + (i*type->size), (char *)area2 + (i*type->size), previous, other_types, all_types, type_id, -1, check_ignore, 0); else @@ -877,21 +902,19 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void } }else{ cursor = 0; - xbt_dynar_foreach(type->members, cursor, member){ + xbt_dynar_foreach(type->members, cursor, member){ if(switch_types) res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, other_types, all_types, member->dw_type_id, -1, check_ignore, 0); else res = compare_heap_area_with_type((char *)real_area1 + member->offset, (char *)real_area2 + member->offset, (char *)area1 + member->offset, (char *)area2 + member->offset, previous, all_types, other_types, member->dw_type_id, -1, check_ignore, 0); - if(res == 1) + if(res == 1){ return res; + } } } break; case e_dw_union_type: - if((check_ignore > 0) && ((ignore1 = heap_comparison_ignore_size(to_ignore1, real_area1)) > 0) && ((ignore2 = heap_comparison_ignore_size(to_ignore2, real_area2)) == ignore1)) - return 0; - else - return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->size, check_ignore); + return compare_heap_area_without_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->size, check_ignore); break; case e_dw_volatile_type: return compare_heap_area_with_type(real_area1, real_area2, area1, area2, previous, all_types, other_types, type->dw_type_id, area_size, check_ignore, pointer_level); @@ -904,6 +927,57 @@ static int compare_heap_area_with_type(void *real_area1, void *real_area2, void } +static char* get_offset_type(char* type_id, int offset, xbt_dict_t all_types, xbt_dict_t other_types, int area_size, int *switch_type){ + dw_type_t type = xbt_dict_get_or_null(all_types, type_id); + if(type == NULL){ + type = xbt_dict_get_or_null(other_types, type_id); + *switch_type = 1; + } + char* type_desc; + switch(type->type){ + case e_dw_structure_type : + if(type->size == 0){ /*declaration of the structure, need the complete description */ + if(*switch_type == 0){ + type_desc = get_type_description(all_types, type->name); + if(type_desc){ + type = xbt_dict_get_or_null(all_types, type_desc); + }else{ + type = xbt_dict_get_or_null(other_types, get_type_description(other_types, type->name)); + *switch_type = 1; + } + }else{ + type_desc = get_type_description(other_types, type->name); + if(type_desc){ + type = xbt_dict_get_or_null(other_types, type_desc); + }else{ + type = xbt_dict_get_or_null(all_types, get_type_description(other_types, type->name)); + *switch_type = 0; + } + } + + } + if(area_size != -1 && type->size != area_size){ + if(area_size>type->size && area_size%type->size == 0) + return type_id; + else + return NULL; + }else{ + unsigned int cursor = 0; + dw_type_t member; + xbt_dynar_foreach(type->members, cursor, member){ + if(member->offset == offset) + return member->dw_type_id; + } + return NULL; + } + break; + default: + /* FIXME : other cases ? */ + return NULL; + break; + } +} + int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t all_types, xbt_dict_t other_types, char *type_id, int pointer_level){ int res_compare; @@ -911,11 +985,15 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t ssize_t size; int check_ignore = 0; - void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2; + void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2, *real_addr_block1, *real_addr_block2, *real_addr_frag1, *real_addr_frag2; void *area1_to_compare, *area2_to_compare; dw_type_t type = NULL; char *type_desc; int type_size = -1; + int offset1 =0, offset2 = 0; + int new_size1 = -1, new_size2 = -1; + char *new_type_id1 = NULL, *new_type_id2 = NULL; + int switch_type = 0; int match_pairs = 0; @@ -946,6 +1024,9 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)heapbase1)); addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)heapbase2)); + real_addr_block1 = ((void*) (((ADDR2UINT(block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase)); + real_addr_block2 = ((void*) (((ADDR2UINT(block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase)); + if(type_id){ type = xbt_dict_get_or_null(all_types, type_id); if(type->size == 0){ @@ -973,8 +1054,8 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t } return 0; - }else if((heapinfo1[block1].type == 0) && (heapinfo2[block2].type == 0)){ /* Complete block */ - + }else if((heapinfo1[block1].type == 0) && (heapinfo2[block2].type == 0)){ /* Complete block */ + if(equals_to1[block1][0] != NULL && equals_to2[block2][0] != NULL){ if(equal_blocks(block1, block2)){ if(match_pairs){ @@ -986,8 +1067,13 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t } if(type_size != -1){ - if(type_size != heapinfo1[block1].busy_block.busy_size && type_size != heapinfo2[block2].busy_block.busy_size && strcmp(type->name, "s_smx_context") != 0) + if(type_size != heapinfo1[block1].busy_block.busy_size && type_size != heapinfo2[block2].busy_block.busy_size && !strcmp(type->name, "s_smx_context")){ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } return -1; + } } if(heapinfo1[block1].busy_block.size != heapinfo2[block2].busy_block.size){ @@ -1013,6 +1099,13 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t } size = heapinfo1[block1].busy_block.busy_size; + + if(type_id != NULL){ + xbt_free(types1[block1][0]); + xbt_free(types2[block2][0]); + types1[block1][0] = strdup(type_id); + types2[block2][0] = strdup(type_id); + } if(size <= 0){ if(match_pairs){ @@ -1035,18 +1128,28 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type; frag2 = ((uintptr_t) (ADDR2UINT (area2) % (BLOCKSIZE))) >> heapinfo2[block2].type; - + addr_frag1 = (void*) ((char *)addr_block1 + (frag1 << heapinfo1[block1].type)); addr_frag2 = (void*) ((char *)addr_block2 + (frag2 << heapinfo2[block2].type)); - - area1_to_compare = addr_frag1; - area2_to_compare = addr_frag2; + + real_addr_frag1 = (void*) ((char *)real_addr_block1 + (frag1 << ((xbt_mheap_t)s_heap)->heapinfo[block1].type)); + real_addr_frag2 = (void*) ((char *)real_addr_block2 + (frag2 << ((xbt_mheap_t)s_heap)->heapinfo[block2].type)); if(type_size != -1){ - if(heapinfo1[block1].busy_frag.frag_size[frag1] == -1 || heapinfo2[block2].busy_frag.frag_size[frag2] == -1) + if(heapinfo1[block1].busy_frag.frag_size[frag1] == -1 || heapinfo2[block2].busy_frag.frag_size[frag2] == -1){ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } return -1; - if(type_size != heapinfo1[block1].busy_frag.frag_size[frag1] || type_size != heapinfo2[block2].busy_frag.frag_size[frag2]) + } + if(type_size != heapinfo1[block1].busy_frag.frag_size[frag1] || type_size != heapinfo2[block2].busy_frag.frag_size[frag2]){ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } return -1; + } } if(equals_to1[block1][frag1] != NULL && equals_to2[block2][frag2] != NULL){ @@ -1061,6 +1164,10 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t if(heapinfo1[block1].busy_frag.frag_size[frag1] != heapinfo2[block2].busy_frag.frag_size[frag2]){ if(type_size == -1){ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } return -1; }else{ if(match_pairs){ @@ -1070,15 +1177,81 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t } } - if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){ - if(match_pairs){ - match_equals(previous); - xbt_dynar_free(&previous); + size = heapinfo1[block1].busy_frag.frag_size[frag1]; + + if(type_id != NULL){ + xbt_free(types1[block1][frag1]); + xbt_free(types2[block2][frag2]); + types1[block1][frag1] = strdup(type_id); + types2[block2][frag2] = strdup(type_id); + } + + if(real_addr_frag1 != area1 || real_addr_frag2 != area2){ + offset1 = (char *)area1 - (char *)real_addr_frag1; + offset2 = (char *)area2 - (char *)real_addr_frag2; + if(types1[block1][frag1] != NULL && types2[block2][frag2] != NULL){ + new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type); + new_type_id2 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type); + }else if(types1[block1][frag1] != NULL){ + new_type_id1 = get_offset_type(types1[block1][frag1], offset1, all_types, other_types, size, &switch_type); + new_type_id2 = get_offset_type(types1[block1][frag1], offset2, all_types, other_types, size, &switch_type); + }else if(types2[block2][frag2] != NULL){ + new_type_id1 = get_offset_type(types2[block2][frag2], offset1, all_types, other_types, size, &switch_type); + new_type_id2 = get_offset_type(types2[block2][frag2], offset2, all_types, other_types, size, &switch_type); + }else{ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } + return -1; + } + + if(new_type_id1 != NULL && new_type_id2 != NULL && !strcmp(new_type_id1, new_type_id2)){ + if(switch_type){ + type = xbt_dict_get_or_null(other_types, new_type_id1); + while(type->size == 0 && type->dw_type_id != NULL) + type = xbt_dict_get_or_null(other_types, type->dw_type_id); + new_size1 = type->size; + type = xbt_dict_get_or_null(other_types, new_type_id2); + while(type->size == 0 && type->dw_type_id != NULL) + type = xbt_dict_get_or_null(other_types, type->dw_type_id); + new_size2 = type->size; + }else{ + type = xbt_dict_get_or_null(all_types, new_type_id1); + while(type->size == 0 && type->dw_type_id != NULL) + type = xbt_dict_get_or_null(all_types, type->dw_type_id); + new_size1 = type->size; + type = xbt_dict_get_or_null(all_types, new_type_id2); + while(type->size == 0 && type->dw_type_id != NULL) + type = xbt_dict_get_or_null(all_types, type->dw_type_id); + new_size2 = type->size; + } + }else{ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } + return -1; } - return 0; } - size = heapinfo1[block1].busy_frag.frag_size[frag1]; + area1_to_compare = (char *)addr_frag1 + offset1; + area2_to_compare = (char *)addr_frag2 + offset2; + + if(new_size1 > 0 && new_size1 == new_size2){ + type_id = new_type_id1; + size = new_size1; + } + + if(offset1 == 0 && offset2 == 0){ + if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){ + if(match_pairs){ + match_equals(previous); + xbt_dynar_free(&previous); + } + return 0; + } + } if(size <= 0){ if(match_pairs){ @@ -1103,15 +1276,21 @@ int compare_heap_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dict_t /* Start comparison*/ if(type_id != NULL){ - res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, type_id, size, check_ignore, pointer_level); - if(res_compare != 0){ + if(switch_type) + res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, type_id, size, check_ignore, pointer_level); + else + res_compare = compare_heap_area_with_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, type_id, size, check_ignore, pointer_level); + if(res_compare == 1){ if(match_pairs) xbt_dynar_free(&previous); return res_compare; } }else{ - res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore); - if(res_compare != 0){ + if(switch_type) + res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, other_types, all_types, size, check_ignore); + else + res_compare = compare_heap_area_without_type(area1, area2, area1_to_compare, area2_to_compare, previous, all_types, other_types, size, check_ignore); + if(res_compare == 1){ if(match_pairs) xbt_dynar_free(&previous); return res_compare; diff --git a/tools/tesh/CMakeLists.txt b/tools/tesh/CMakeLists.txt index 2587afbbb3..3ed17582b5 100644 --- a/tools/tesh/CMakeLists.txt +++ b/tools/tesh/CMakeLists.txt @@ -10,7 +10,7 @@ if(WIN32) "${CMAKE_BINARY_DIR}/bin/tesh" @ONLY IMMEDIATE) file(COPY ${CMAKE_HOME_DIRECTORY}/buildtools/Cmake/Scripts/Diff.pm - DESTINATION ${CMAKE_BINARY_DIR} + DESTINATION ${CMAKE_BINARY_DIR}/bin FILE_PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)