Add parallel build support for perf tests.
authorDoug Evans <dje@google.com>
Mon, 3 Aug 2015 16:17:40 +0000 (09:17 -0700)
committerDoug Evans <dje@google.com>
Mon, 3 Aug 2015 16:17:40 +0000 (09:17 -0700)
gdb/testsuite/ChangeLog:

* Makefile.in (workers/%.worker, build-perf): New rule.
(GDB_PERFTEST_MODE): New variable.
(check-perf): Use it.
(clean): Clean up gdb.perf parallel build subdirs.
* lib/build-piece.exp: New file.
* lib/gdb.exp (make_gdb_parallel_path): New function
(standard_output_file, standard_temp_file): Call it.
(GDB_PARALLEL handling): Make outputs,temp,cache directories as subdirs
of $GDB_PARALLEL.
* lib/cache.exp (gdb_do_cache): Call make_gdb_parallel_path.

gdb/testsuite/ChangeLog
gdb/testsuite/Makefile.in
gdb/testsuite/lib/build-piece.exp [new file with mode: 0644]
gdb/testsuite/lib/cache.exp
gdb/testsuite/lib/gdb.exp

index 3e1ad7b12e898cefcf44c8f48c2fb4c681f4c8d8..eab972489e012881449b39eaa421069d8c183d82 100644 (file)
@@ -1,3 +1,16 @@
+2015-08-03  Doug Evans  <dje@google.com>
+
+       * Makefile.in (workers/%.worker, build-perf): New rule.
+       (GDB_PERFTEST_MODE): New variable.
+       (check-perf): Use it.
+       (clean): Clean up gdb.perf parallel build subdirs.
+       * lib/build-piece.exp: New file.
+       * lib/gdb.exp (make_gdb_parallel_path): New function
+       (standard_output_file, standard_temp_file): Call it.
+       (GDB_PARALLEL handling): Make outputs,temp,cache directories as subdirs
+       of $GDB_PARALLEL.
+       * lib/cache.exp (gdb_do_cache): Call make_gdb_parallel_path.
+
 2015-08-03  Doug Evans  <dje@google.com>
 
        * lib/perftest/reporter.py (SUM_FILE_NAME): New global.
index c064f06fc742b7552ae75b93cd31e26346f8e20d..3ad5feb4e8a3b4df95dddb8a676fd3bee3dbe948 100644 (file)
@@ -234,9 +234,41 @@ check/no-matching-tests-found:
        @echo "No matching tests found."
        @echo ""
 
+# Utility rule invoked by step 2 of the build-perf rule.
+@GMAKE_TRUE@workers/%.worker:
+@GMAKE_TRUE@   mkdir -p gdb.perf/outputs/$*
+@GMAKE_TRUE@   $(DO_RUNTEST) --status --outdir=gdb.perf/outputs/$* lib/build-piece.exp WORKER=$* GDB_PARALLEL=gdb.perf $(RUNTESTFLAGS) GDB_PERFTEST_MODE=compile GDB_PERFTEST_SUBMODE=build-pieces
+
+# Utility rule to build tests that support it in parallel.
+# The build is broken into 3 steps distinguished by GDB_PERFTEST_SUBMODE:
+# gen-workers, build-pieces, final.
+#
+# GDB_PERFTEST_MODE appears *after* RUNTESTFLAGS here because we don't want
+# anything in RUNTESTFLAGS to override it.
+#
+# We don't delete the outputs directory here as these programs can take
+# awhile to build, and perftest.exp has support for deciding whether to
+# recompile them.  If you want to remove these directories, make clean.
+#
+# The point of step 1 is to construct the set of worker tasks for step 2.
+# All of the information needed by build-piece.exp is contained in the name
+# of the generated .worker file.
+@GMAKE_TRUE@build-perf: $(abs_builddir)/site.exp
+@GMAKE_TRUE@   rm -rf gdb.perf/workers
+@GMAKE_TRUE@   mkdir -p gdb.perf/workers
+@GMAKE_TRUE@   @: Step 1: Generate the build .worker files.
+@GMAKE_TRUE@   $(DO_RUNTEST) --status --directory=gdb.perf --outdir gdb.perf/workers GDB_PARALLEL=gdb.perf $(RUNTESTFLAGS) GDB_PERFTEST_MODE=compile GDB_PERFTEST_SUBMODE=gen-workers
+@GMAKE_TRUE@   @: Step 2: Compile the pieces.  Here is the build parallelism.
+@GMAKE_TRUE@   $(MAKE) $$(cd gdb.perf && echo workers/*/*.worker)
+@GMAKE_TRUE@   @: Step 3: Do the final link.
+@GMAKE_TRUE@   $(DO_RUNTEST) --status --directory=gdb.perf --outdir gdb.perf GDB_PARALLEL=gdb.perf $(RUNTESTFLAGS) GDB_PERFTEST_MODE=compile GDB_PERFTEST_SUBMODE=final
+
+# The default is to both compile and run the tests.
+GDB_PERFTEST_MODE = both
+
 check-perf: all $(abs_builddir)/site.exp
        @if test ! -d gdb.perf; then mkdir gdb.perf; fi
-       $(DO_RUNTEST) --directory=gdb.perf --outdir gdb.perf GDB_PERFTEST_MODE=both $(RUNTESTFLAGS)
+       $(DO_RUNTEST) --directory=gdb.perf --outdir gdb.perf GDB_PERFTEST_MODE=$(GDB_PERFTEST_MODE) $(RUNTESTFLAGS)
 
 force:;
 
@@ -245,6 +277,7 @@ clean mostlyclean:
        -rm -f core.* *.tf *.cl tracecommandsscript copy1.txt zzz-gdbscript
        -rm -f *.dwo *.dwp
        -rm -rf outputs temp cache
+       -rm -rf gdb.perf/workers gdb.perf/outputs gdb.perf/temp gdb.perf/cache
        -rm -f read1.so expect-read1
        if [ x"${ALL_SUBDIRS}" != x ] ; then \
            for dir in ${ALL_SUBDIRS}; \
diff --git a/gdb/testsuite/lib/build-piece.exp b/gdb/testsuite/lib/build-piece.exp
new file mode 100644 (file)
index 0000000..a81530c
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program 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, see <http://www.gnu.org/licenses/>.
+
+# Utility to bootstrap building a piece of a performance test in a
+# parallel build.
+# See testsuite/Makefile.in:workers/%.worker.
+# WORKER is set by the makefile and is
+# "{program_name}/{program_name}-{worker_nr}".
+
+regexp "^\(.+\)/\(.+\)-\(\[0-9\]+\)$" $WORKER entire_match PROGRAM_NAME pname2 WORKER_NR
+
+if { ![info exists entire_match] || $entire_match != $WORKER } {
+    error "Bad value for WORKER: $WORKER"
+}
+if { $PROGRAM_NAME != $pname2 } {
+    error "Bad value for WORKER: $WORKER"
+}
+
+# $subdir is set to "lib", because that is where this file lives,
+# which is not what tests expect.
+set subdir "gdb.perf"
+
+# $gdb_test_file_name is set to this file, build-piece, which is not what
+# tests expect.
+set gdb_test_file_name $PROGRAM_NAME
+
+source $srcdir/$subdir/${gdb_test_file_name}.exp
index 8df04b9a58014f9b862eab99d49b798c729a1af9..968e9ffa04e20216c5077d484cb36815c7a79e28 100644 (file)
@@ -35,7 +35,7 @@ proc gdb_do_cache {name} {
     }
 
     if {[info exists GDB_PARALLEL]} {
-       set cache_filename [file join $objdir cache $cache_name]
+       set cache_filename [make_gdb_parallel_path cache $cache_name]
        if {[file exists $cache_filename]} {
            set fd [open $cache_filename]
            set gdb_data_cache($cache_name) [read -nonewline $fd]
index 986d92079463165dd7c33e7ffe79a43df42ab6b5..5659906c0b9e590762aff6f74d97cdd81fb9a727 100644 (file)
@@ -4073,6 +4073,26 @@ proc default_gdb_init { test_file_name } {
     }
 }
 
+# Return a path using GDB_PARALLEL.
+# ARGS is a list of path elements to append to "$objdir/$GDB_PARALLEL".
+# GDB_PARALLEL must be defined, the caller must check.
+#
+# The default value for GDB_PARALLEL is, canonically, ".".
+# The catch is that tests don't expect an additional "./" in file paths so
+# omit any directory for the default case.
+# GDB_PARALLEL is written as "yes" for the default case in Makefile.in to mark
+# its special handling.
+
+proc make_gdb_parallel_path { args } {
+    global GDB_PARALLEL objdir
+    set joiner [list "file" "join" $objdir]
+    if { $GDB_PARALLEL != "yes" } {
+       lappend joiner $GDB_PARALLEL
+    }
+    set joiner [concat $joiner $args]
+    return [eval $joiner]
+}
+
 # Turn BASENAME into a full file name in the standard output
 # directory.  It is ok if BASENAME is the empty string; in this case
 # the directory is returned.
@@ -4081,7 +4101,7 @@ proc standard_output_file {basename} {
     global objdir subdir gdb_test_file_name GDB_PARALLEL
 
     if {[info exists GDB_PARALLEL]} {
-       set dir [file join $objdir outputs $subdir $gdb_test_file_name]
+       set dir [make_gdb_parallel_path outputs $subdir $gdb_test_file_name]
        file mkdir $dir
        return [file join $dir $basename]
     } else {
@@ -4095,7 +4115,7 @@ proc standard_temp_file {basename} {
     global objdir GDB_PARALLEL
 
     if {[info exists GDB_PARALLEL]} {
-       return [file join $objdir temp $basename]
+       return [make_gdb_parallel_path temp $basename]
     } else {
        return $basename
     }
@@ -5220,7 +5240,10 @@ if {[info exists GDB_PARALLEL]} {
     if {[is_remote host]} {
        unset GDB_PARALLEL
     } else {
-       file mkdir outputs temp cache
+       file mkdir \
+           [make_gdb_parallel_path outputs] \
+           [make_gdb_parallel_path temp] \
+           [make_gdb_parallel_path cache]
     }
 }