Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
authorPierre Veyre <pierre.veyre@cc.in2p3.fr>
Sun, 6 Oct 2013 14:39:14 +0000 (16:39 +0200)
committerPierre Veyre <pierre.veyre@cc.in2p3.fr>
Sun, 6 Oct 2013 14:39:14 +0000 (16:39 +0200)
21 files changed:
buildtools/Cmake/Scripts/tesh.pl
examples/msg/mc/bugged1_liveness.c
examples/msg/mc/bugged1_liveness.tesh
examples/msg/mc/bugged1_liveness_visited.tesh
examples/msg/mc/centralized_mutex.c
examples/simdag/dot/dot_test.c
examples/smpi/mc/bugged1_liveness.c
include/smpi/smpi.h
include/xbt/mmalloc.h
src/mc/mc_compare.c
src/mc/mc_dpor.c
src/mc/mc_global.c
src/mc/mc_liveness.c
src/msg/msg_mailbox.c
src/simix/smx_global.c
src/simix/smx_synchro.c
src/simix/smx_user.c
src/smpi/smpi_base.c
src/smpi/smpi_pmpi.c
src/xbt/mmalloc/mm_diff.c
tools/tesh/CMakeLists.txt

index a7e5ddc..31acb42 100755 (executable)
@@ -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<tesh> [I<options>] I<tesh_file>
 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=<OUT>)) {
-       $got =~ s/\r//g;
-       $got =~ s/^( )*//g;
-       chomp $got;
+  # pop all output from executing child
+  my @got;
+  while(defined(my $got=<OUT>)) {
+    $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=<TESH_FILE>)) {
+my $finished =0;
+LINE: while (not $finished and not $error) {
+  my $line;
+
+
+  if ($tesh_file ne "(stdin)" and !defined($line=<TESH_FILE>)){
+    $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=<TESH_FILE>;
+    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=<TESH_FILE>;
-       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;
 }
 
 
index bd59651..b6949dd 100644 (file)
@@ -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{
index d3a29d7..3413fbb 100644 (file)
@@ -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
+
 
 
 
index 932946f..49d40fc 100644 (file)
@@ -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
index 64008b4..3403c88 100644 (file)
@@ -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
index 4456c2f..e586334 100644 (file)
@@ -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);
   }
index 4b5b067..eab2b55 100644 (file)
@@ -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;
index eaf6fac..710e5da 100644 (file)
@@ -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));
index 0e64852..9708a76 100644 (file)
@@ -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);
index b580233..7f2ea63 100644 (file)
@@ -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);
index 4209fac..643acf8 100644 (file)
@@ -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 */
index 558fca0..2fba00d 100644 (file)
@@ -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;
index 6f977cd..2007c64 100644 (file)
@@ -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); 
index 907ecdf..83840e5 100644 (file)
@@ -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
index bfed0ba..7af670a 100644 (file)
@@ -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();
   }
index cd9645b..c9d14d0 100644 (file)
@@ -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();
index bcc6ba8..a4453a8 100644 (file)
@@ -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,
index bb00f04..eed7b81 100644 (file)
@@ -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; i<count; i++){
-    if(requests[i]!= MPI_REQUEST_NULL){
+    if (requests[i] != MPI_REQUEST_NULL && !(requests[i]->flags & 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]);
index bcbe9b9..f9a06a5 100644 (file)
@@ -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);
index 86733e3..49c5968 100644 (file)
@@ -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; j<MAX_FRAGMENT_PER_BLOCK; j++)
+    types1[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+    for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
       equals_to1[i][j] = NULL;
+      types1[i][j] = NULL;
+    }      
   }
 
-
   equals_to2 = malloc(heaplimit * sizeof(heap_area_t *));
+  types2 = malloc(heaplimit * sizeof(type_name *));
   for(i=0; i<=heaplimit; i++){
     equals_to2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(heap_area_t));
-    for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++)
+    types2[i] = malloc(MAX_FRAGMENT_PER_BLOCK * sizeof(type_name));
+    for(j=0; j<MAX_FRAGMENT_PER_BLOCK; j++){
       equals_to2[i][j] = NULL;
+      types2[i][j] = NULL;
+    }
   }
 
   if(MC_is_active()){
@@ -355,6 +365,8 @@ int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t i1,
     MC_ignore_global_variable("to_ignore2");
     MC_ignore_global_variable("equals_to1");
     MC_ignore_global_variable("equals_to2");
+    MC_ignore_global_variable("types1");
+    MC_ignore_global_variable("types2");
   }
 
   return 0;
@@ -365,29 +377,38 @@ void reset_heap_information(){
 
   size_t i = 0, j;
 
-  for(i=0; i<heaplimit; i++){
+  for(i=0; i<=heaplimit; i++){
     for(j=0; j<MAX_FRAGMENT_PER_BLOCK;j++){
       heap_area_free(equals_to1[i][j]);
       equals_to1[i][j] = NULL;
       heap_area_free(equals_to2[i][j]);
       equals_to2[i][j] = NULL;
+      xbt_free(types1[i][j]);
+      types1[i][j] = NULL;
+      xbt_free(types2[i][j]);
+      types2[i][j] = NULL;
     }
     free(equals_to1[i]);
     free(equals_to2[i]);
+    free(types1[i]);
+    free(types2[i]);
   }
 
   free(equals_to1);
   free(equals_to2);
+  free(types1);
+  free(types2);
 
   s_heap = NULL, heapbase1 = NULL, heapbase2 = NULL;
   heapinfo1 = NULL, heapinfo2 = NULL;
   heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
   to_ignore1 = NULL, to_ignore2 = NULL;
   equals_to1 = NULL, equals_to2 = NULL;
+  types1 = NULL, types2 = NULL;
 
 }
 
-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){
 
   if(heap1 == NULL && heap2 == NULL){
     XBT_DEBUG("Malloc descriptors null");
@@ -443,9 +464,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));
         
-          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<size){
 
     if(check_ignore > 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; i<type->size; i++){
+    for(i=0; i<type->size; 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;
index 2587afb..3ed1758 100644 (file)
@@ -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)