blob: 4c8f04fe2aeee24e7232de5e1a9827eeba1e5abe [file] [log] [blame]
# Copyright (C) 2021-2024 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
use strict;
package acct;
use vars qw(%Acct $Erp);
my($debug_f, $retVal, $OpenDis, $OpenFsingle, $Read_rules_txt);
my(@Comparison, @hashSample, @acctHeader);
my(%RANGE, %Rules);
my($ERROR_ACCT_MISMATCH, $ERROR_NEGATIVE_TIME, $ERROR_PERL_ERROR,
$ERROR_DIFF_RANGE, $ERROR_ZERO_METRIC, $ERROR_HIGH_UNKNOWN,
$ERROR_CALLER_VERIF, $ERROR_SIGNAL_LOST);
BEGIN {
# use Exporter ();
# @ISA = 'Exporter';
# @EXPORT_OK = ('&readAcct', '%Acct');
$debug_f = $ENV{PERL_DEBUG};
$retVal = 0;
$OpenDis = 0;
$OpenFsingle = 0;
$#Comparison = -1;
$Read_rules_txt = 0;
$Erp = {};
@hashSample = [];
%RANGE = (
Count => { P_RANGE => 0, P_RATE => 0,
N_RANGE => 0, N_RATE => 0, FMT => "%d"
},
Total => { P_RANGE => 0.20, P_RATE => 3,
N_RANGE => -0.20, N_RATE => -3, FMT => "%6.3f"
},
Cpu => { P_RANGE => 0.5, P_RATE => 10,
N_RANGE => -0.5, N_RATE => -10, FMT => "%6.3f"
,P_RANGE_2AVG => 0.5, P_RATE_2AVG => 10,
N_RANGE_2AVG => -0.5, N_RATE_2AVG => -10
},
Cycles => { P_RANGE => 0.5, P_RATE => 10,
N_RANGE => -0.5, N_RATE => -10, FMT => "%6.3f"
,P_RANGE_2AVG => 0.5, P_RATE_2AVG => 10,
N_RANGE_2AVG => -0.5, N_RATE_2AVG => -10
},
Cycles1 => { P_RANGE => 0.5, P_RATE => 10,
N_RANGE => -0.5, N_RATE => -10, FMT => "%6.3f"
,P_RANGE_2AVG => 0.5, P_RATE_2AVG => 10,
N_RANGE_2AVG => -0.5, N_RATE_2AVG => -10
},
Sync => { P_RANGE => 0.5, P_RATE => 3,
N_RANGE => -0.5, N_RATE => -3, FMT => "%6.3f"
},
Unkn => { P_RANGE => 0.10, P_RATE => 0.5, FMT => "%6.3f" }
);
$ERROR_SIGNAL_LOST = 44;
$ERROR_DIFF_RANGE = 84;
$ERROR_HIGH_UNKNOWN = 85;
$ERROR_PERL_ERROR = 86;
$ERROR_ACCT_MISMATCH = 87;
$ERROR_CALLER_VERIF = 88;
$ERROR_ZERO_METRIC = 94;
$ERROR_NEGATIVE_TIME = 103;
}
sub debug
{
my ($lineN, $fmt);
if ( $debug_f == 0 ) {
return;
}
$lineN = shift @_;
$fmt = shift @_;
if ( $debug_f == 2 ) {
warn "DEBUG:#$lineN:\n";
}
warn sprintf($fmt, @_);
}
sub set_retVal
{
if ( $retVal == 0 ) {
$retVal = $_[0];
if ($retVal != 0 ) {
my $s = "";
if ($retVal == $ERROR_DIFF_RANGE) {
$s = "Difference out of range";
} elsif ($retVal == $ERROR_HIGH_UNKNOWN) {
$s = "High unknown detected";
} elsif ($retVal == $ERROR_ACCT_MISMATCH) {
$s = "Accounting file mismatch";
} elsif ($retVal == $ERROR_CALLER_VERIF) {
$s = "Caller/caller verification failed";
} elsif ($retVal == $ERROR_ZERO_METRIC) {
$s = "Unexpected zero metric";
} elsif ($retVal == $ERROR_NEGATIVE_TIME) {
$s = "Negative CPU time";
}
warn sprintf("DEBUG: retVal=%d %s\n", $retVal, $s);
}
}
return $retVal;
}
sub diffRule
{
# The format of the comparison rule is:
# <Name>, <Column number in *.acct>, <Column number in erprint.out>, <message>
# Cpu, 3, 1
# Total, 2, 3
my ($str) = @_;
my (@arr);
@arr = split (/,/, $str);
if ($#arr == 2) {
# Old version
push @arr, $arr[0];
}
push @Comparison, [@arr];
}
sub read_rules
{
my ($name, $rule, $line, @arr);
return if ( $Read_rules_txt == 1);
$Read_rules_txt = 1;
open(FP, "<rules.txt") or return;
while ($line = <FP>) {
chomp ($line);
$line =~ s/\s*//g; # Remove all blanks
$line =~ s/\\s/ /g; # Replace \s with space
next if ( $line =~ m/^$/ );
next if ( $line =~ m/^#/ );
if ( $line =~ m/=/ ) {
# Set a calculation rule
($name, $rule) = split (/=/, $line);
$Rules{$name} = [split(/\+/, $rule)];
next;
}
# Set a comparison rule
&diffRule($line);
}
close(FP);
}
sub dump_acct()
{
my ($i, $n, $key, $fmt, @fmt_head);
printf "dump_acct:\n";
foreach $i ( @acctHeader ) {
$fmt = sprintf("%%%ds ", length($i));
push @fmt_head, $fmt;
printf $fmt, $i;
}
printf "\n";
foreach $key (sort keys %Acct) {
$n = 0;
foreach $i ( @{$Acct{$key}} ) {
$fmt = $n <= $#fmt_head ? $fmt_head[$n] : " %10s";
$n++;
printf $fmt, $i;
}
printf " '%s'", $key;
if ( exists $Rules{$key} ) {
printf " := %s", join(" + ", @{$Rules{$key}});
}
printf "\n";
}
}
sub readAcct
{
# Read the *.acct file into hash $Acct with the function name as key.
# The format of *.acct is :
# X <time1> ... <timeN> <func_name>
my ($fileName, @checkTime) = @_;
my ($name, $i, $key, $line, @arr);
# file *.acct is generated while the test program is running.
if (!open(FP, "<$fileName")) {
printf "acct::readAcct: Cannot open '%s'\n\n", $fileName;
exit($ERROR_ACCT_MISMATCH);
}
while ($line = <FP>) { # Skip the first lines (header)
last if ( $line =~ m/^X\s+/ );
}
@acctHeader = split (/\s+/, $line);
push @acctHeader, "Comment";
while ($line = <FP>) {
chomp($line);
$line =~ s/^\s*//; # Delete leading spaces
next if ( $line =~ m/^$/ );
@arr = split (/\s+/, $line);
$name = pop(@arr);
if (defined $Acct{$name}) {
for ($i = 1; $i <= $#arr; $i++ ) {
$Acct{$name}[$i] += $arr[$i];
}
} else {
$Acct{$name} = [ @arr ];
}
foreach $i ( @checkTime ) {
next if ($i > $#arr);
if ( $arr[$i] < 0 ) {
&set_retVal($ERROR_NEGATIVE_TIME);
last;
}
}
}
close(FP);
&read_rules;
# &checkCallersCallees;
if ( $debug_f != 0 ) {
printf "\nreadAcct: '%s'\n", $fileName;
printf "checkTime: ";
if( $#checkTime == -1 ) {
printf "<None>\n";
} else {
print "[ ", join(", ", @checkTime), " ]\n";
}
foreach $i ( @Comparison ) {
print "Comparison rule: ", join(", ", @{$i}), "\n";
}
&dump_acct;
printf "\n";
}
}
sub read_er_print_out
{
my ($fileName, $colName) = @_;
my ($name, @arr, $head_f, $line, $key, $i);
$Erp = {};
$head_f = 1;
open(FP, "<$fileName") or return;
while ($line = <FP>) {
chomp($line);
$line =~ s/^\s*//; # Delete leading spaces
next if ( $line =~ m/^$/ );
if ($head_f == 1) {
# Skip the first lines (header)
next unless ( $line =~ m/^\d/ );
next unless ( ($line =~ m/<Total>\s*$/) ||
($line =~ m/<Stack-unwind-failed>\s*$/) );
$head_f = 0;
if ($colName == -1) {
@arr = split (/\s+/, $line);
$colName = $#arr + 1;
}
}
@arr = split (/\s+/, $line, $colName);
$name = pop(@arr);
if (defined $Erp->{$name}) {
for ($i = 0; $i <= $#arr; $i++ ) {
$Erp->{$name}[$i] += $arr[$i];
}
} else {
$Erp->{$name} = [ @arr ];
}
$i = index($name, "(");
if ($i > 0) {
my $funcName = substr($name, 0, $i);
if (defined $Erp->{$funcName}) {
for ($i = 0; $i <= $#arr; $i++ ) {
$Erp->{$funcName}[$i] += $arr[$i];
}
} else {
$Erp->{$funcName} = [ @arr ];
}
}
}
close(FP);
if ( $debug_f != 0 ) {
printf "read_er_print_out:\n";
foreach $key (sort keys %{$Erp}) {
foreach $i ( @{$Erp->{$key}} ) {
printf " %10s", $i;
}
printf " %-10s", "'$key'";
if ( exists $Rules{$key} ) {
printf " += %s", join(" + ", @{$Rules{$key}});
}
printf "\n";
}
}
}
sub createKDiff
{
my ($colSample) = @_;
my ($key, $str, $i, $head_str);
open(DIFF_fp, ">diff.out");
$head_str = "X";
for $i ( 0..$#Comparison ) {
$head_str .= &get_head_str($i);
}
$head_str .= " Name";
printf DIFF_fp "%s\n", $head_str;
foreach $key (sort keys %Acct) {
# Restore a hash 'Erp'
$Erp = $hashSample[$Acct{$key}[$colSample]];
$str = &doComp($key, $head_str);
printf DIFF_fp "%s (Sample %d)\n", $str,$Acct{$key}[$colSample];
}
close(DIFF_fp);
&closeDisFile();
}
sub commandToScr1_fp()
{
my ($str) = @_;
printf Scr1_fp "#\n#%s\n%s\n", $str, $str;
}
sub openFsingleScr
{
return if ($OpenFsingle == 1);
open(Scr1_fp, ">>erp_fsingle.scr");
$OpenFsingle = 1;
}
sub closeFsingleScr
{
return if ($OpenFsingle != 1);
$OpenFsingle = 2;
close(Scr1_fp);
}
sub openDisFile
{
&openFsingleScr();
return if ($OpenDis == 1);
open(Dis_fp, ">>discrepancy.out");
$OpenDis = 1;
}
sub closeDisFile
{
&closeFsingleScr();
return if ($OpenDis != 1);
$OpenDis = 2;
close(Dis_fp);
}
sub with_diff
{
my ($i) = @_;
my ($key);
$key = $Comparison[$i][0];
if( ! exists $RANGE{$key} ) {
printf "acct::with_diff: '$key' is a wrong key\n\n";
exit $ERROR_PERL_ERROR;
}
if ($RANGE{$key}->{FMT} !~ m/^%d/) {
return 1;
}
return 0;
}
sub get_head_str()
{
my ($i) = @_;
my ($str);
$str = $Comparison[$i][3];
while (length($str) < 16) {
$str = "*" . $str . "*";
}
if (with_diff($i)) {
return sprintf("| %17s %7s %7s %s", $str, "Diff", "%", "x");
} else {
return sprintf("| %17s %s", $str, "x");
}
}
sub doComp
{
my ($fname, $head_str) = @_;
my ($key, $R, $r1, $r2, $diff, $rate, $flagX, $x, $i,
$retStr, $discrepancy, $err_diff_range, $err_zero_metric, $err_acct_mismatch);
sub setRate
{
my ($val, $diff) = @_;
return sprintf("%6.1f", ($diff/$val)*100) if ( $val != 0 );
return sprintf("%6.1f", "0.0") if ( $diff >= -0.05 && $diff <= 0.05);
return sprintf("%6.1f", "100") if ( $diff > 0 );
return sprintf("%6.1f", "-100");
}
$err_diff_range = 0;
$err_zero_metric = 0;
$err_acct_mismatch = 0;
$discrepancy = " ";
$flagX = " ";
$retStr = "";
for $i ( 0..$#Comparison ) {
$r1 = $Acct{$fname}[$Comparison[$i][1]];
$r2 = 0;
if ( ! exists $Rules{$fname} ) {
if ( exists $Erp->{$fname} ) {
$r2 = $Erp->{$fname}[$Comparison[$i][2]];
}
} else {
foreach my $key1 ( @{$Rules{$fname}} ) {
my $sign = 1;
$key = $key1;
if (substr($key1, 0, 1) eq '-') {
$key = substr($key1, 1);
$sign = -1;
}
if ( exists $Erp->{$key} ) {
$r2 += $sign * $Erp->{$key}[$Comparison[$i][2]];
}
}
}
$key = $Comparison[$i][0];
if( ! exists $RANGE{$key} ) {
printf "acct::doComp: '$key' is a wrong key\n\n";
exit $ERROR_PERL_ERROR;
}
$R = $RANGE{$key};
$r1 = sprintf($R->{FMT}, $r1);
$r2 = sprintf($R->{FMT}, $r2);
$diff = sprintf($R->{FMT}, $r1 - $r2);
$rate = &setRate($r1, $diff);
if ((( $diff > $R->{P_RANGE} ) && ( $rate >= $R->{P_RATE} ))
|| ( ( $fname ne '<Unknown>') && ( $diff < $R->{N_RANGE} ) && ( $rate <= $R->{N_RATE} ))) {
$x = ($Acct{$fname}[0] eq "Y") ? "y" : "x";
if ( $x ne "y" ) {
$flagX = "X";
&openDisFile();
printf Dis_fp "%s/ %s\n", $fname, $Comparison[$i][3];
$discrepancy .= " $Comparison[$i][3]";
if (with_diff($i)) {
if ( $r2 > 0 ) {
$err_diff_range = $ERROR_DIFF_RANGE;
} else {
if (! exists $ENV{ACCT_FILTER}) {
$err_zero_metric = $ERROR_ZERO_METRIC;
}
}
} else {
$err_acct_mismatch = $ERROR_ACCT_MISMATCH;
}
}
} else {
$x = " ";
}
if (with_diff($i)) {
$retStr .= sprintf("| %8s %8s %7s %7s %s", $r1, $r2, $diff, $rate, $x);
} else {
$retStr .= sprintf("| %8s %8s %s", $r1, $r2, $x);
}
}
$retStr = $flagX . $retStr . sprintf(" %-10s", $fname);
if ( exists $Rules{$fname} ) {
$retStr .= sprintf " := %s", join(" + ", @{$Rules{$fname}});
}
if ($discrepancy ne " ") {
if ($err_acct_mismatch != 0) {
$retVal = $err_acct_mismatch;
}
&set_retVal($err_zero_metric);
&set_retVal($err_diff_range);
printf Scr1_fp "#%s\n#%s\n", $head_str, $retStr;
&commandToScr1_fp(sprintf("%s %s 1", 'fsingle', $fname));
&commandToScr1_fp(sprintf("%s %s 1", 'csingle', $fname));
}
return ($retStr);
}
sub doComp2AVG
{
my ($fname, $head_str, @avg) = @_;
my ($key, $R, $r1, $r2, $diff, $rate, $flagX, $x, $i,
$retStr, $discrepancy, $err_diff_range, $err_zero_metric, $err_acct_mismatch);
sub setRate
{
my ($val, $diff) = @_;
return sprintf("%6.1f", ($diff/$val)*100) if ( $val != 0 );
return sprintf("%6.1f", "0.0") if ( $diff >= -0.05 && $diff <= 0.05);
return sprintf("%6.1f", "100") if ( $diff > 0 );
return sprintf("%6.1f", "-100");
}
$err_diff_range = 0;
$err_zero_metric = 0;
$err_acct_mismatch = 0;
$discrepancy = " ";
$flagX = " ";
$retStr = "";
for $i ( 0..$#Comparison ) {
$r1 = $avg[$i];
$r2 = 0;
if ( ! exists $Rules{$fname} ) {
if ( exists $Erp->{$fname} ) {
$r2 = $Erp->{$fname}[$Comparison[$i][2]];
}
} else {
foreach my $key1 ( @{$Rules{$fname}} ) {
my $sign = 1;
$key = $key1;
if (substr($key1, 0, 1) eq '-') {
$key = substr($key1, 1);
$sign = -1;
}
if ( exists $Erp->{$key} ) {
$r2 += $sign * $Erp->{$key}[$Comparison[$i][2]];
}
}
}
$key = $Comparison[$i][0];
if( ! exists $RANGE{$key} ) {
printf "acct::doComp: '$key' is a wrong key\n\n";
exit $ERROR_PERL_ERROR;
}
$R = $RANGE{$key};
$r1 = sprintf($R->{FMT}, $r1);
$r2 = sprintf($R->{FMT}, $r2);
$diff = sprintf($R->{FMT}, $r1 - $r2);
$rate = &setRate($r1, $diff);
if ((( $diff > $R->{P_RANGE_2AVG} ) && ( $rate >= $R->{P_RATE_2AVG} ))
|| ( ( $fname ne '<Unknown>') && ( $diff < $R->{N_RANGE_2AVG} ) && ( $rate <= $R->{N_RATE_2AVG} ))) {
$flagX = "X";
$x = "x";
$discrepancy .= " $Comparison[$i][3]";
if (with_diff($i)) {
if ( $r2 > 0 ) {
$err_diff_range = $ERROR_DIFF_RANGE;
} else {
if (! exists $ENV{ACCT_FILTER}) {
$err_zero_metric = $ERROR_ZERO_METRIC;
}
}
} else {
$err_acct_mismatch = $ERROR_ACCT_MISMATCH;
}
} else {
$x = " ";
}
if (with_diff($i)) {
$retStr .= sprintf("| %8s %8s %7s %7s %s", $r1, $r2, $diff, $rate, $x);
} else {
$retStr .= sprintf("| %8s %8s %s", $r1, $r2, $x);
}
}
$retStr = $flagX . $retStr . sprintf(" %-10s", $fname);
if ( exists $Rules{$fname} ) {
$retStr .= sprintf " := %s", join(" + ", @{$Rules{$fname}});
}
if ($discrepancy ne " ") {
if ($err_acct_mismatch != 0) {
$retVal = $err_acct_mismatch;
}
&set_retVal($err_zero_metric);
&set_retVal($err_diff_range);
&openDisFile();
printf Scr1_fp "#%s\n#%s\n", $head_str, $retStr;
&commandToScr1_fp(sprintf("%s %s 1", 'fsingle', $fname));
printf Dis_fp "%s/%s\n", $fname, $discrepancy;
} else {
}
return ($retStr);
}
sub checkUnknown()
{
my ($total, $i, $R);
sub checkUnknRate()
{
my ($name, $N) = @_;
my ($val, $rate, $fmt);
$val = $Erp->{$name}[$Comparison[$N][2]];
$val = sprintf($R->{FMT}, $val);
$rate = sprintf($R->{FMT},($val / $total) * 100);
if ((! exists $ENV{ACCT_FILTER}) &&
($val > $R->{'P_RANGE'}) && ($rate > $R->{'P_RATE'})) {
&set_retVal($ERROR_HIGH_UNKNOWN);
&openFsingleScr();
$fmt = "#%-8s %10s %10s %s\n";
printf Scr1_fp $fmt, $Comparison[$N][0], '%', '<Total>', $name;
printf Scr1_fp $fmt, ' ', $rate, $total, $val;
&commandToScr1_fp(sprintf("%s %s 1", 'fsingle', '<Total>'));
&commandToScr1_fp(sprintf("%s %s 1", 'csingle', '<Total>'));
&commandToScr1_fp(sprintf("%s %s 1", 'fsingle', $name));
&commandToScr1_fp(sprintf("%s %s 1", 'csingle', $name));
&closeFsingleScr();
return 1;
}
return 0;
}
return if ( ! exists $Erp->{'<Total>'} );
return if ( $ENV{NOJAVA} );
$R = $RANGE{'Unkn'};
for $i ( 0..$#Comparison ) {
$total = $Erp->{'<Total>'}[$Comparison[$i][2]];
next if ( $total == 0 );
$total = sprintf($R->{FMT}, $total);
# last if &checkUnknRate('<Stack-unwind-failed>', $i);
last if &checkUnknRate('<Unknown>', $i);
last if &checkUnknRate('<no', $i);
}
}
sub createDiff
{
my ($key, $str, $i, $head_str);
&checkUnknown();
open(DIFF_fp, ">diff.out");
$head_str = " ";
for $i ( 0..$#Comparison ) {
printf DIFF_fp "Comparison[%d]: %s,%d,%d\n", $i,
$Comparison[$i][0], $Comparison[$i][1], $Comparison[$i][2], $Comparison[$i][3];
$head_str .= &get_head_str($i);
}
printf DIFF_fp "\nX| Compare the acct file (first column) with the er_print output (second column):\n";
$head_str .= " Name";
printf DIFF_fp "%s\n", $head_str;
foreach $key (sort keys %Acct) {
$str = &doComp($key, $head_str);
printf DIFF_fp "%s\n", $str;
}
&checkCallersCallees;
close(DIFF_fp);
&closeDisFile();
return -s "discrepancy.out"
}
sub createDiff2AVG
{
my ($key, $str, $i, $n, $head_str, @avg, $temp, $fname);
&checkUnknown();
open(DIFF_fp, ">>diff.out");
printf DIFF_fp "\n==================\n";
$head_str = " ";
for $i ( 0..$#Comparison ) {
printf DIFF_fp "Comparison[%d]: %s,%d\n", $i,
$Comparison[$i][0], $Comparison[$i][2];
$head_str .= &get_head_str($i);
}
printf DIFF_fp "\n#| Compare the avg value (first column) with the er_print output (second column):\n";
$head_str .= " Name";
printf DIFF_fp "%s\n", $head_str;
for $i ( 0..$#Comparison ) {
$avg[$i] = 0;
}
$n=0;
foreach $fname (sort keys %Acct) {
$n++;
for $i ( 0..$#Comparison ) {
if ( ! exists $Rules{$fname} ) {
if ( exists $Erp->{$fname} ) {
$temp = $Erp->{$fname}[$Comparison[$i][2]];
}
} else {
foreach my $key1 ( @{$Rules{$fname}} ) {
my $sign = 1;
$key = $key1;
if (substr($key1, 0, 1) eq '-') {
$key = substr($key1, 1);
$sign = -1;
}
if ( exists $Erp->{$key} ) {
$temp += $sign * $Erp->{$key}[$Comparison[$i][2]];
}
}
}
$avg[$i] += $temp;
}
}
for $i ( 0..$#Comparison ) {
$avg[$i] /= $n;
}
foreach $key (sort keys %Acct) {
$str = &doComp2AVG($key, $head_str, @avg);
printf DIFF_fp "%s\n", $str;
}
close(DIFF_fp);
&closeDisFile();
}
sub sumOutlinedCode
{ # Add a time of the outlined code.
my ($name, $eName);
foreach $name (keys %Acct) {
foreach $eName (keys %$Erp) {
next if ("$eName" !~ m/^($name)\s--/);
if (defined $Rules{$name}) {
push @{$Rules{$name}}, $eName;
} else {
$Rules{$name} = [$eName];
}
}
}
}
sub checkCallersCallees
{
my (@arr, $name, $colName, $line, $nline, %Calls);
open(FP, "<caller_callee.out") or return;
while ($line = <FP>) {
last if ( $line =~ m/\s+sec.\s+/ );
}
$nline = 0;
while ($line = <FP>) {
chomp($line);
$line =~ s/^\s*//; # Delete leading spaces
next if ( $line =~ m/^$/ );
@arr = split (/\s+/, $line, $colName);
$name = pop(@arr);
# New Callers-Callees format does not have * in the Stack Fragment section
# - translate old format to new format for compatibility
if ($name eq "*MAIN") { $name = "MAIN"; };
last if ($name eq "MAIN");
$nline += 1;
}
if ($nline == 0) {
printf "checkCallersCallees: No Callers of MAIN\n";
&set_retVal($ERROR_CALLER_VERIF);
close(FP);
return;
}
while ($line = <FP>) {
chomp($line);
$line =~ s/^\s*//; # Delete leading spaces
next if ( $line =~ m/^$/ );
@arr = split (/\s+/, $line, $colName);
$name = pop(@arr);
$Calls{$name} = 1;
if ( $line =~ /Parallel/ ) { #f90synprog M_EXPERT or M_MACHINE
@arr = split (/\s\s+/, $line, $colName);
$name = pop(@arr);
@arr = split (/\s/, $name);
$Calls{$arr[0]} = 1;
}
}
close(FP);
foreach $name (sort keys %Acct) {
next if ( $name eq '<Total>' ) ;
next if ( $name eq '<Unknown>' ) ;
next if (defined $Calls{$name}) ;
printf "checkCallersCallees: '$name' is not inside callees\n";
&set_retVal($ERROR_CALLER_VERIF);
}
}
return 1;
END{}