1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#! /usr/bin/perl
2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--------------------------------------------------------------------##
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--- Valgrind performance testing script                  vg_perf ---##
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--------------------------------------------------------------------##
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  This file is part of Valgrind, a dynamic binary instrumentation
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  framework.
8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  Copyright (C) 2005 Nicholas Nethercote
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#     njn@valgrind.org
11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  This program is free software; you can redistribute it and/or
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  modify it under the terms of the GNU General Public License as
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  published by the Free Software Foundation; either version 2 of the
15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  License, or (at your option) any later version.
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  This program is distributed in the hope that it will be useful, but
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  WITHOUT ANY WARRANTY; without even the implied warranty of
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  General Public License for more details.
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  You should have received a copy of the GNU General Public License
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  along with this program; if not, write to the Free Software
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  02111-1307, USA.
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  The GNU General Public License is contained in the file COPYING.
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# usage: see usage message.
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# You can specify individual files to test, or whole directories, or both.
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Directories are traversed recursively, except for ones named, for example, 
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# CVS/ or docs/.
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Each test is defined in a file <test>.vgperf, containing one or more of the
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# following lines, in any order:
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#   - prog:   <prog to run>                         (compulsory)
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#   - args:   <args for prog>                       (default: none)
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#   - vgopts: <Valgrind options>                    (default: none)
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#   - prereq: <prerequisite command>                (default: none)
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#   - cleanup: <post-test cleanup cmd to run>       (default: none)
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# The prerequisite command, if present, must return 0 otherwise the test is
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# skipped.
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Sometimes it is useful to run all the tests at a high sanity check
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# level or with arbitrary other flags.  To make this simple, extra 
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# options, applied to all tests run, are read from $EXTRA_REGTEST_OPTS,
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# and handed to valgrind prior to any other flags specified by the 
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# .vgperf file. Note: the env var is the same as vg_regtest.
51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse warnings;
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse strict;
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Global vars
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $usage = <<END
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovusage: vg_perf [options] [files or dirs]
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  options for the user, with defaults in [ ], are:
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    -h --help             show this message
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --reps=<n>            number of repeats for each program [1]
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --tools=<t1,t2,t3>    tools to run [Nulgrind and Memcheck]
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --vg=<dir>            top-level directory containing Valgrind to measure
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          [Valgrind in the current directory, i.e. --vg=.]
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          Can be specified multiple times.
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          The "in-place" build is used.
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --outer-valgrind: run these Valgrind(s) under the given outer valgrind.
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      These Valgrind(s) must be configured with --enable-inner.
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --outer-tool: tool to use by the outer valgrind (default cachegrind).
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    --outer-args: use this as outer tool args.
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Any tools named in --tools must be present in all directories specified
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  with --vg.  (This is not checked.)
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  Use EXTRA_REGTEST_OPTS to supply extra args for all tests
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovEND
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov;
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Test variables
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $vgopts;             # valgrind options
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $prog;               # test prog
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $args;               # test prog args
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $prereq;             # prerequisite test to satisfy before running test
87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $cleanup;            # cleanup command to run
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Command line options
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $n_reps = 1;         # Run each test $n_reps times and choose the best one.
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy @vgdirs;             # Dirs of the various Valgrinds being measured.
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy @tools = ("none", "memcheck");   # tools being measured
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Outer valgrind to use, and args to use for it.
95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# If this is set, --valgrind should be set to the installed inner valgrind,
96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# and --valgrind-lib will be ignore
97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $outer_valgrind;
98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $outer_tool = "cachegrind";
99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $outer_args;
100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $num_tests_done   = 0;
103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $num_timings_done = 0;
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Starting directory
106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovchomp(my $tests_dir = `pwd`);
107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Process command line, setup
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# If $prog is a relative path, it prepends $dir to it.  Useful for two reasons:
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# 1. Can prepend "." onto programs to avoid trouble with users who don't have
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#    "." in their path (by making $dir = ".")
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# 2. Can prepend the current dir to make the command absolute to avoid
117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#    subsequent trouble when we change directories.
118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Also checks the program exists and is executable.
120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub validate_program ($$$$) 
121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($dir, $prog, $must_exist, $must_be_executable) = @_;
123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # If absolute path, leave it alone.  If relative, make it
125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # absolute -- by prepending current dir -- so we can change
126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # dirs and still use it.
127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    $prog = "$dir/$prog" if ($prog !~ /^\//);
128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($must_exist) {
129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (-f $prog) or die "vg_perf: '$prog' not found or not a file ($dir)\n";
130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($must_be_executable) { 
132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (-x $prog) or die "vg_perf: '$prog' not executable ($dir)\n";
133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return $prog;
136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub add_vgdir($)
139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($vgdir) = @_;
141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($vgdir !~ /^\//) { $vgdir = "$tests_dir/$vgdir"; }
142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    push(@vgdirs, $vgdir);
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub process_command_line() 
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my @fs;
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    for my $arg (@ARGV) {
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($arg =~ /^-/) {
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if ($arg =~ /^--reps=(\d+)$/) {
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $n_reps = $1;
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                if ($n_reps < 1) { die "bad --reps value: $n_reps\n"; }
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } elsif ($arg =~ /^--vg=(.+)$/) {
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # Make dir absolute if not already
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                add_vgdir($1);
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } elsif ($arg =~ /^--tools=(.+)$/) {
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                @tools = split(/,/, $1);
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } elsif ($arg =~ /^--outer-valgrind=(.*)$/) {
160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $outer_valgrind = $1;
161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } elsif ($arg =~ /^--outer-tool=(.*)$/) {
162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $outer_tool = $1;
163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } elsif ($arg =~ /^--outer-args=(.*)$/) {
164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $outer_args = $1;
165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                die $usage;
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } else {
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            push(@fs, $arg);
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # If no --vg options were specified, use the current tree.
174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (0 == @vgdirs) {
175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        add_vgdir($tests_dir);
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    (0 != @fs) or die "No test files or directories specified\n";
179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return @fs;
181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Read a .vgperf file
185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub read_vgperf_file($)
187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($f) = @_;
189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Defaults.
191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ($vgopts, $prog, $args, $prereq, $cleanup)
192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      = ("", undef, "", undef, undef, undef, undef);
193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    open(INPUTFILE, "< $f") || die "File $f not openable\n";
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    while (my $line = <INPUTFILE>) {
197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if      ($line =~ /^\s*#/ || $line =~ /^\s*$/) {
198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov	    next;
199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov	} elsif ($line =~ /^\s*vgopts:\s*(.*)$/) {
200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $vgopts = $1;
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif ($line =~ /^\s*prog:\s*(.*)$/) {
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $prog = validate_program(".", $1, 1, 1);
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif ($line =~ /^\s*args:\s*(.*)$/) {
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $args = $1;
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif ($line =~ /^\s*prereq:\s*(.*)$/) {
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $prereq = $1;
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif ($line =~ /^\s*cleanup:\s*(.*)$/) {
208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $cleanup = $1;
209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } else {
210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            die "Bad line in $f: $line\n";
211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    close(INPUTFILE);
214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (!defined $prog) {
216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        $prog = "";     # allow no prog for testing error and --help cases
217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (0 == @tools) {
219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        die "vg_perf: missing 'tools' line in $f\n";
220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Do one test
225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Since most of the program time is spent in system() calls, need this to
227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# propagate a Ctrl-C enabling us to quit.
228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub mysystem($) 
229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($cmd) = @_;
231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $retval = system($cmd);
232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($retval == 2) { 
233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        exit 1; 
234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } else {
235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return $retval;
236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Run program N times, return the best user time.  Use the POSIX
240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# -p flag on /usr/bin/time so as to get something parseable on AIX.
241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub time_prog($$)
242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($cmd, $n) = @_;
244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $tmin = 999999;
245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    for (my $i = 0; $i < $n; $i++) {
246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        mysystem("echo '$cmd' > perf.cmd");
247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $retval = mysystem("$cmd > perf.stdout 2> perf.stderr");
248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (0 == $retval) or 
249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            die "\n*** Command returned non-zero ($retval)"
250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              . "\n*** See perf.{cmd,stdout,stderr} to determine what went wrong.\n";
251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $out = `cat perf.stderr`;
252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        ($out =~ /[Uu]ser +([\d\.]+)/) or 
253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            die "\n*** missing usertime in perf.stderr\n";
254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        $tmin = $1 if ($1 < $tmin);
255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Successful run; cleanup
258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    unlink("perf.cmd");
259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    unlink("perf.stderr");
260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    unlink("perf.stdout");
261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Avoid divisions by zero!
263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return (0 == $tmin ? 0.01 : $tmin);
264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub do_one_test($$) 
267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($dir, $vgperf) = @_;
269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    $vgperf =~ /^(.*)\.vgperf/;
270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $name = $1;
271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my %first_tTool;    # For doing percentage speedups when comparing
272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        # multiple Valgrinds
273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    read_vgperf_file($vgperf);
275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (defined $prereq) {
277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (system("$prereq") != 0) {
278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            printf("%-16s (skipping, prereq failed: $prereq)\n", "$name:");
279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            return;
280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $timecmd = "/usr/bin/time -p";
284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Do the native run(s).
286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    printf("-- $name --\n") if (@vgdirs > 1);
287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $cmd     = "$timecmd $prog $args";
288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $tNative = time_prog($cmd, $n_reps);
289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (defined $outer_valgrind) {
291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        $outer_valgrind = validate_program($tests_dir, $outer_valgrind, 1, 1);
292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        foreach my $vgdir (@vgdirs) {
293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            validate_program($vgdir, "./coregrind/valgrind", 1, 1);
294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } else {
296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        foreach my $vgdir (@vgdirs) {
297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            validate_program($vgdir, "./coregrind/valgrind", 1, 1);
298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Pull any extra options (for example, --sanity-level=4)
302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # from $EXTRA_REGTEST_OPTS.
303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $maybe_extraopts = $ENV{"EXTRA_REGTEST_OPTS"};
304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $extraopts = $maybe_extraopts ?  $maybe_extraopts  : "";
305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $vgdir (@vgdirs) {
307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        # Benchmark name
308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        printf("%-8s ", $name);
309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        # Print the Valgrind version if we are measuring more than one.
311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $vgdirname = $vgdir;
312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        chomp($vgdirname = `basename $vgdir`);
313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        printf("%-10s:", $vgdirname);
314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        
315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        # Native execution time
316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        printf("%4.2fs", $tNative);
317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        foreach my $tool (@tools) {
319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # First two chars of toolname for abbreviation
320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $tool_abbrev = $tool;
321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $tool_abbrev =~ s/(..).*/$1/;
322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            printf("  %s:", $tool_abbrev);
323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $run_outer_args = "";
324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (not defined $outer_args) {
325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $run_outer_args = 
326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                      " -v --command-line-only=yes"
327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --run-libc-freeres=no --sim-hints=enable-outer"
328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --smc-check=all-non-file"
329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --vgdb=no --trace-children=yes --read-var-info=no"
330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --suppressions=../tests/outer_inner.supp"
331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --memcheck:leak-check=full --memcheck:show-reachable=no"
332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --cachegrind:cache-sim=yes --cachegrind:branch-sim=yes"
333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --cachegrind:cachegrind-out-file=cachegrind.out.$vgdirname.$tool_abbrev.$name.%p"
334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --callgrind:cache-sim=yes --callgrind:branch-sim=yes"
335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --callgrind:dump-instr=yes --callgrind:collect-jumps=yes"
336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " --callgrind:callgrind-out-file=callgrind.out.$vgdirname.$tool_abbrev.$name.%p"
337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    . " ";
338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $run_outer_args = $outer_args;
340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $vgsetup = "";
343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $vgcmd   = "$vgdir/coregrind/valgrind "
344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        . "--command-line-only=yes --tool=$tool  $extraopts -q "
345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        . "--memcheck:leak-check=no "
346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        . "--trace-children=yes "
347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        . "$vgopts ";
348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # Do the tool run(s).
349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (defined $outer_valgrind ) {
350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # in an outer-inner setup, only set VALGRIND_LIB_INNER
351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $vgsetup = "VALGRIND_LIB_INNER=$vgdir/.in_place ";
352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $vgcmd   = "$outer_valgrind "
353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . "--tool=" . $outer_tool . " "
354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . "$run_outer_args "
355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . "--log-file=" . "$outer_tool.outer.log.$vgdirname.$tool_abbrev.$name.%p "
356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . $vgcmd;
357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # Set both VALGRIND_LIB and VALGRIND_LIB_INNER
359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # in case this Valgrind was configured with --enable-inner.  And
360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # also VALGRINDLIB, which was the old name for the variable, to
361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                # allow comparison against old Valgrind versions (eg. 2.4.X).
362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $vgsetup = "VALGRINDLIB=$vgdir/.in_place "
363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . "VALGRIND_LIB=$vgdir/.in_place "
364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         . "VALGRIND_LIB_INNER=$vgdir/.in_place ";
365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $cmd     = "$vgsetup $timecmd $vgcmd $prog $args";
367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $tTool   = time_prog($cmd, $n_reps);
368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            printf("%4.1fs (%4.1fx,", $tTool, $tTool/$tNative);
369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # If it's the first timing for this tool on this benchmark,
371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # record the time so we can get the percentage speedup of the
372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # subsequent Valgrinds.  Otherwise, compute and print
373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # the speedup.
374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (not defined $first_tTool{$tool}) {
375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                $first_tTool{$tool} = $tTool;
376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                print(" -----)");
377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                my $speedup = 100 - (100 * $tTool / $first_tTool{$tool});
379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                printf("%5.1f%%)", $speedup);
380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $num_timings_done++;
383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (defined $cleanup) {
385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                (system("$cleanup") == 0) or 
386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    print("  ($name cleanup operation failed: $cleanup)\n");
387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        printf("\n");
390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    $num_tests_done++;
393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Test one directory (and any subdirs)
397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub test_one_dir($$);    # forward declaration
399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub test_one_dir($$) 
401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($dir, $prev_dirs) = @_;
403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    $dir =~ s/\/$//;    # trim a trailing '/'
404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    chomp(my $initial_dir = `pwd`);     # record where we started
406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Ignore dirs into which we should not recurse.
408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($dir =~ /^(BitKeeper|CVS|SCCS|docs|doc)$/) { return; }
409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    chdir($dir) or die "Could not change into $dir\n";
411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    # Nb: Don't prepend a '/' to the base directory
413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $full_dir = $prev_dirs . ($prev_dirs eq "" ? "" : "/") . $dir;
414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $dashes = "-" x (50 - length $full_dir);
415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my @fs = glob "*";
417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $found_tests = (0 != (grep { $_ =~ /\.vgperf$/ } @fs));
418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($found_tests) {
420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        print "-- Running  tests in $full_dir $dashes\n";
421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $f (@fs) {
423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (-d $f) {
424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            test_one_dir($f, $full_dir);
425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif ($f =~ /\.vgperf$/) {
426436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            do_one_test($full_dir, $f);
427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($found_tests) {
430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        print "-- Finished tests in $full_dir $dashes\n";
431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    chdir("$initial_dir");
434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Summarise results
438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub summarise_results 
440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    printf("\n== %d programs, %d timings =================\n\n", 
442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           $num_tests_done, $num_timings_done);
443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# main()
447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#----------------------------------------------------------------------------
448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub warn_about_EXTRA_REGTEST_OPTS()
449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "WARNING: \$EXTRA_REGTEST_OPTS is set.  You probably don't want\n";
451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "to run the perf tests with it set, unless you are doing some\n";
452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "strange experiment, and/or you really know what you are doing.\n";
453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "\n";
454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# nuke VALGRIND_OPTS
457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov$ENV{"VALGRIND_OPTS"} = "";
458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovif ($ENV{"EXTRA_REGTEST_OPTS"}) {
460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "\n";
461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    warn_about_EXTRA_REGTEST_OPTS();
462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy @fs = process_command_line();
465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovforeach my $f (@fs) {
466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (-d $f) {
467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        test_one_dir($f, "");
468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } else { 
469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        # Allow the .vgperf suffix to be given or omitted
470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($f =~ /.vgperf$/ && -r $f) {
471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            # do nothing
472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } elsif (-r "$f.vgperf") {
473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $f = "$f.vgperf";
474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        } else {
475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            die "`$f' neither a directory nor a readable test file/name\n"
476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $dir  = `dirname  $f`;   chomp $dir;
478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $file = `basename $f`;   chomp $file;
479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        chdir($dir) or die "Could not change into $dir\n";
480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        do_one_test($dir, $file);
481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        chdir($tests_dir);
482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsummarise_results();
485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovif ($ENV{"EXTRA_REGTEST_OPTS"}) {
487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    warn_about_EXTRA_REGTEST_OPTS();
488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
490436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--------------------------------------------------------------------##
491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--- end                                                          ---##
492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov##--------------------------------------------------------------------##
493