This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] gcc parallel make check


On Fri, Sep 12, 2014 at 09:47:00AM +0000, VandeVondele  Joost wrote:
> Obviously, if Jakub's patch can be made to work around the testsuite
> special cases, I believe it should be superior.  If not, the attached
> patch is working as far as I can tell, and provides a significant
> improvement over current trunk.

Here is my latest version of the patch.

With this patch I get identical test_summary output on make -k check
(completely serial testing) and make -j48 -k check from toplevel directory.

Major changes since last version:
1) I've changed the granularity, now it does O_EXCL|O_CREAT attempt
   only every 10th runtest_file_p invocation rather than every iteration,
   so that it spends a little bit less time in expect processes (especially
   if used on slower networked filesystems etc.)
2) in guality.exp I've discovered that it counts as PASS/FAIL also the
   initial check whether any guality tests should be performed; that stuff
   isn't runtest_file_p guarded (of course, needs to be performed by every
   runtest instance), but made the totals dependent on how many runtest
   instances invoked guality.exp; IMHO we don't want the pass/fail counts
   to be volatile, so I've fixed it by not counting that test into the
   results
3) various other *.exp fails didn't use runtest_file_p, especially the
   gcc.misc-tests/ ones, tweaked those like struct-layout-1.exp or
   plugin.exp so that only the first runtest instance to encounter those
   runs all of the *.exp file serially
4) fixed go-test.exp so that runtest_file_p used for a test that
   has been already runtest_file_p checked is not testing for parallel
   execution - otherwise the numbers in go-parallel/ directory could be
   different between different instances
5) libstdc++-v3/testsuite has been changed too to use the same stuff;
   note that the new xmethods.exp apparently isn't invoked for
   parallel testing, but it hasn't been before either (and the tree
   I've been testing on the 16way box still didn't have it).  Either
   it should be tested serially like abi.exp or pretty-printers.exp,
   or needs to be double-checked for parallel testing (guess it
   could have similar issues as guality.exp)
6) changed -a to ] && [

Regtested on x86_64-linux, ok for trunk?

2014-09-12  Jakub Jelinek  <jakub@redhat.com>

gcc/
	* Makefile.in (dg_target_exps): Remove.
	(check_gcc_parallelize): Change to just an upper bound number.
	(check-%-subtargets): Always print the non-parallelized goals.
	(check_p_vars, check_p_comma, check_p_subwork): Remove.
	(check_p_count, check_p_numbers0, check_p_numbers1, check_p_numbers2,
	check_p_numbers3, check_p_numbers4, check_p_numbers5,
	check_p_numbers6): New variables.
	(check_p_numbers): Set to sequence from 1 to 9999.
	(check_p_subdirs): Set to sequence from 1 to minimum of
	$(check_p_count) and either GCC_TEST_PARALLEL_SLOTS env var if set,
	or 128.
	(check-%, check-parallel-%): Rewritten so that for parallelized
	testing each job runs all the *.exp files, with
	GCC_RUNTEST_PARALLELIZE_DIR set in environment.
gcc/go/
	* Make-lang.in (check_go_parallelize): Change to just an upper bound
	number.
gcc/fortran/
	* Make-lang.in (check_gfortran_parallelize): Change to just an upper
	bound number.
gcc/cp/
	* Make-lang.in (check_g++_parallelize): Change to just an upper bound
	number.
gcc/objc/
	* Make-lang.in (check_objc_parallelize): Change to just an upper
	bound number.
gcc/testsuite/
	* lib/gcc-defs.exp (gcc_parallel_test_run_p,
	gcc_parallel_test_enable): New procedures.  If
	GCC_RUNTEST_PARALLELIZE_DIR is set in environment, override
	runtest_file_p to invoke also gcc_parallel_test_run_p.
	* g++.dg/guality/guality.exp (check_guality): Save/restore
	test_counts array around the body of the procedure.
	* gcc.dg/guality/guality.exp (check_guality): Likewise.
	* g++.dg/compat/struct-layout-1.exp: Run all the tests serially
	by the first parallel runtest encountering it.
	* g++.dg/plugin/plugin.exp: Likewise.
	* gcc.dg/compat/struct-layout-1.exp: Likewise.
	* gcc.dg/plugin/plugin.exp: Likewise.
	* objc.dg/gnu-encoding/gnu-encoding.exp: Likewise.
	* gcc.misc-tests/matrix1.exp: Likewise.
	* gcc.misc-tests/dhry.exp: Likewise.
	* gcc.misc-tests/acker1.exp: Likewise.
	* gcc.misc-tests/linkage.exp: Likewise.
	* gcc.misc-tests/mg.exp: Likewise.
	* gcc.misc-tests/mg-2.exp: Likewise.
	* gcc.misc-tests/sort2.exp: Likewise.
	* gcc.misc-tests/sieve.exp: Likewise.
	* gcc.misc-tests/options.exp: Likewise.
	* gcc.misc-tests/help.exp: Likewise.
	* go.test/go-test.exp (go-gc-tests): Use
	gcc_parallel_test_enable {0, 1} around all handling of
	each test.
libstdc++-v3/
	* testsuite/Makefile.am (check_p_numbers0, check_p_numbers1,
	check_p_numbers2, check_p_numbers3, check_p_numbers4,
	check_p_numbers5, check_p_numbers6, check_p_numbers,
	check_p_subdirs): New variables.
	(check_DEJAGNU_normal_targets): Use check_p_subdirs.
	(check-DEJAGNU): Rewritten so that for parallelized
	testing each job runs all the *.exp files, with
	GCC_RUNTEST_PARALLELIZE_DIR set in environment.
	* testsuite/Makefile.in: Regenerated.
	* testsuite/lib/libstdc++.exp (gcc_parallel_test_run_p,
	gcc_parallel_test_enable): New procedures.  If
	GCC_RUNTEST_PARALLELIZE_DIR is set in environment, override
	runtest_file_p to invoke also gcc_parallel_test_run_p.

--- gcc/Makefile.in.jj	2014-09-11 20:35:28.603749840 +0200
+++ gcc/Makefile.in	2014-09-12 11:25:50.245338490 +0200
@@ -513,34 +513,10 @@ xm_include_list=@xm_include_list@
 xm_defines=@xm_defines@
 lang_checks=
 lang_checks_parallelized=
-dg_target_exps:=aarch64.exp,alpha.exp,arm.exp,avr.exp,bfin.exp,cris.exp
-dg_target_exps:=$(dg_target_exps),epiphany.exp,frv.exp,i386.exp,ia64.exp
-dg_target_exps:=$(dg_target_exps),m68k.exp,microblaze.exp,mips.exp,powerpc.exp
-dg_target_exps:=$(dg_target_exps),rx.exp,s390.exp,sh.exp,sparc.exp,spu.exp
-dg_target_exps:=$(dg_target_exps),tic6x.exp,xstormy16.exp
-# This lists a couple of test files that take most time during check-gcc.
-# When doing parallelized check-gcc, these can run in parallel with the
-# remaining tests.  Each word in this variable stands for work for one
-# make goal and one extra make goal is added to handle all the *.exp
-# files not handled explicitly already.  If multiple *.exp files
-# should be run in the same runtest invocation (usually if they aren't
-# very long running, but still should be split of from the check-parallel-$lang
-# remaining tests runtest invocation), they should be concatenated with commas.
-# Note that [a-zA-Z] wildcards need to have []s prefixed with \ (needed
-# by tcl) and as the *.exp arguments are mached both as is and with
-# */ prefixed to it in runtest_file_p, it is usually desirable to include
-# a subdirectory name.
-check_gcc_parallelize=execute.exp=execute/2* \
-		      execute.exp=execute/\[013-9a-fA-F\]* \
-		      execute.exp=execute/\[pP\]*,dg.exp \
-		      execute.exp=execute/\[g-oq-zG-OQ-Z\]*,compile.exp=compile/2* \
-		      compile.exp=compile/\[9pP\]*,builtins.exp \
-		      compile.exp=compile/\[013-8a-oq-zA-OQ-Z\]* \
-		      dg-torture.exp,ieee.exp \
-		      vect.exp,unsorted.exp \
-		      guality.exp \
-		      struct-layout-1.exp,stackalign.exp \
-		      $(dg_target_exps)
+# Upper limit to which it is useful to parallelize this lang target.
+# It doesn't make sense to try e.g. 128 goals for small testsuites
+# like objc or go.
+check_gcc_parallelize=10000
 lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt
 lang_specs_files=@lang_specs_files@
 lang_tree_files=@lang_tree_files@
@@ -3631,27 +3607,32 @@ $(filter-out $(lang_checks_parallelized)
 	    export TCL_LIBRARY ; fi ; \
 	$(RUNTEST) --tool $* $(RUNTESTFLAGS))
 
-$(patsubst %,%-subtargets,$(filter-out $(lang_checks_parallelized),$(lang_checks))): check-%-subtargets:
+$(patsubst %,%-subtargets,$(lang_checks)): check-%-subtargets:
 	@echo check-$*
 
 check_p_tool=$(firstword $(subst _, ,$*))
-check_p_vars=$(check_$(check_p_tool)_parallelize)
+check_p_count=$(check_$(check_p_tool)_parallelize)
 check_p_subno=$(word 2,$(subst _, ,$*))
-check_p_comma=,
-check_p_subwork=$(subst $(check_p_comma), ,$(if $(check_p_subno),$(word $(check_p_subno),$(check_p_vars))))
-check_p_numbers=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+check_p_numbers0:=1 2 3 4 5 6 7 8 9
+check_p_numbers1:=0 $(check_p_numbers0)
+check_p_numbers2:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers1)))
+check_p_numbers3:=$(patsubst %,0%,$(check_p_numbers1)) $(check_p_numbers2)
+check_p_numbers4:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers3)))
+check_p_numbers5:=$(patsubst %,0%,$(check_p_numbers3)) $(check_p_numbers4)
+check_p_numbers6:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers5)))
+check_p_numbers:=$(check_p_numbers0) $(check_p_numbers2) $(check_p_numbers4) $(check_p_numbers6)
 check_p_subdir=$(subst _,,$*)
-check_p_subdirs=$(wordlist 1,$(words $(check_$*_parallelize)),$(check_p_numbers))
+check_p_subdirs=$(wordlist 1,$(check_p_count),$(wordlist 1,$(or $(GCC_TEST_PARALLEL_SLOTS),128),$(check_p_numbers)))
 
 # For parallelized check-% targets, this decides whether parallelization
 # is desirable (if -jN is used and RUNTESTFLAGS doesn't contain anything
 # but optional --target_board or --extra_opts arguments).  If desirable,
 # recursive make is run with check-parallel-$lang{,1,2,3,4,5} etc. goals,
 # which can be executed in parallel, as they are run in separate directories.
-# check-parallel-$lang{1,2,3,4,5} etc. goals invoke runtest with the longest
-# running *.exp files from the testsuite, as determined by check_$lang_parallelize
-# variable.  The check-parallel-$lang goal in that case invokes runtest with
-# all the remaining *.exp files not handled by the separate goals.
+# check-parallel-$lang{,1,2,3,4,5} etc. goals invoke runtest with
+# GCC_RUNTEST_PARALLELIZE_DIR var in the environment and runtest_file_p
+# dejaGNU procedure is overridden to additionally synchronize through
+# a $lang-parallel directory which tests will be run by which runtest instance.
 # Afterwards contrib/dg-extract-results.sh is used to merge the sum and log
 # files.  If parallelization isn't desirable, only one recursive make
 # is run with check-parallel-$lang goal and check_$lang_parallelize variable
@@ -3662,76 +3643,61 @@ check_p_subdirs=$(wordlist 1,$(words $(c
 # to lang_checks_parallelized variable and define check_$lang_parallelize
 # variable (see above check_gcc_parallelize description).
 $(lang_checks_parallelized): check-% : site.exp
+	-rm -rf $(TESTSUITEDIR)/$*-parallel
 	@if [ -z "$(filter-out --target_board=%,$(filter-out --extra_opts%,$(RUNTESTFLAGS)))" ] \
 	    && [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
+	  test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) || true; \
+	  test -d $(TESTSUITEDIR)/$*-parallel || mkdir $(TESTSUITEDIR)/$*-parallel || true; \
+	  GCC_RUNTEST_PARALLELIZE_DIR=`${PWD_COMMAND}`/$(TESTSUITEDIR)/$(check_p_tool)-parallel ; \
+	  export GCC_RUNTEST_PARALLELIZE_DIR ; \
 	  $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \
 	    check-parallel-$* \
 	    $(patsubst %,check-parallel-$*_%, $(check_p_subdirs)); \
-	  for file in $(TESTSUITEDIR)/$*/$* \
-		      $(patsubst %,$(TESTSUITEDIR)/$*%/$*,$(check_p_subdirs));\
+	  sums= ; logs= ; \
+	  for dir in $(TESTSUITEDIR)/$* \
+		     $(patsubst %,$(TESTSUITEDIR)/$*%,$(check_p_subdirs));\
 	  do \
-	    mv -f $$file.sum $$file.sum.sep; mv -f $$file.log $$file.log.sep; \
+	    if [ -d $$dir ]; then \
+	      mv -f $$dir/$*.sum $$dir/$*.sum.sep; mv -f $$dir/$*.log $$dir/$*.log.sep; \
+	      sums="$$sums $$dir/$*.sum.sep"; logs="$$logs $$dir/$*.log.sep"; \
+	    fi; \
 	  done; \
-	  $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh \
-	    $(TESTSUITEDIR)/$*/$*.sum.sep \
-	    $(patsubst %,$(TESTSUITEDIR)/$*%/$*.sum.sep,$(check_p_subdirs)) \
+	  $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh $$sums \
 	    > $(TESTSUITEDIR)/$*/$*.sum; \
-	  $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L \
-	    $(TESTSUITEDIR)/$*/$*.log.sep \
-	    $(patsubst %,$(TESTSUITEDIR)/$*%/$*.log.sep,$(check_p_subdirs)) \
+	  $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L $$logs \
 	    > $(TESTSUITEDIR)/$*/$*.log; \
+	  rm -rf $(TESTSUITEDIR)/$*-parallel || true; \
 	else \
 	  $(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \
 	    check_$*_parallelize= check-parallel-$*; \
 	fi
 
-# Just print the parallelized subtargets for those that want to split
-# the testing across machines.
-$(patsubst %,%-subtargets,$(lang_checks_parallelized)): check-%-subtargets:
-	@echo check-parallel-$* \
-	  $(patsubst %,check-parallel-$*_%, $(check_p_subdirs))
-
-# In the if [ -n "$(check_p_subno)" ] case runtest should be given the name of
-# the given *.exp file(s).  See comment above check_gcc_parallelize variable
-# for details on the content of these variables.
-#
-# In the elif [ -n "$(check_p_vars)" ] case runtest should be given
-# names of all the *.exp files for this tool that aren't already handled by
-# other goals.  First it finds all the *.exp files for this tool, then
-# prunes those already specified in check_$lang_parallelize or duplicates.
-#
-# Otherwise check-$lang isn't parallelized and runtest is invoked just with
-# the $(RUNTESTFLAGS) arguments.
 check-parallel-% : site.exp
 	-test -d plugin || mkdir plugin
 	-test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR)
 	test -d $(TESTSUITEDIR)/$(check_p_subdir) || mkdir $(TESTSUITEDIR)/$(check_p_subdir)
 	-(rootme=`${PWD_COMMAND}`; export rootme; \
 	srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
-	cd $(TESTSUITEDIR)/$(check_p_subdir); \
-	rm -f tmp-site.exp; \
-	sed '/set tmpdir/ s|testsuite$$|$(TESTSUITEDIR)/$(check_p_subdir)|' \
+	if [ -n "$(check_p_subno)" ] \
+	   && [ -n "$$GCC_RUNTEST_PARALLELIZE_DIR" ] \
+	   && [ -f $(TESTSUITEDIR)/$(check_p_tool)-parallel/finished ]; then \
+	  rm -rf $(TESTSUITEDIR)/$(check_p_subdir); \
+	else \
+	  cd $(TESTSUITEDIR)/$(check_p_subdir); \
+	  rm -f tmp-site.exp; \
+	  sed '/set tmpdir/ s|testsuite$$|$(TESTSUITEDIR)/$(check_p_subdir)|' \
 		< ../../site.exp > tmp-site.exp; \
-	$(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \
-	EXPECT=${EXPECT} ; export EXPECT ; \
-	if [ -f $${rootme}/../expect/expect ] ; then  \
-	   TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
-	    export TCL_LIBRARY ; fi ; \
-	runtestflags= ; \
-	if [ -n "$(check_p_subno)" ] ; then \
-	  runtestflags="$(check_p_subwork)"; \
-	elif [ -n "$(check_p_vars)" ] ; then \
-	  parts="`echo ' $(strip $(subst $(check_p_comma), ,$(check_p_vars))) ' \
-		  | sed 's/=[^ ]* / /g'`"; \
-	  for part in `find $$srcdir/testsuite/$(check_p_tool)* -name \*.exp` ; do \
-	    part=`basename $$part` ; \
-	    case " $$parts $$runtestflags " in \
-	      *" $$part "*) ;; \
-	      *) runtestflags="$$runtestflags $$part" ;; \
-	    esac ; \
-	  done ; \
-	fi ; \
-	$(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS) $$runtestflags)
+	  $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \
+	  EXPECT=${EXPECT} ; export EXPECT ; \
+	  if [ -f $${rootme}/../expect/expect ] ; then  \
+	    TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
+	    export TCL_LIBRARY ; \
+	  fi ; \
+	  $(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS); \
+	  if [ -n "$$GCC_RUNTEST_PARALLELIZE_DIR" ] ; then \
+	    touch $${rootme}/$(TESTSUITEDIR)/$(check_p_tool)-parallel/finished; \
+	  fi ; \
+	fi )
 
 # QMTest targets
 
--- gcc/go/Make-lang.in.jj	2014-09-11 20:35:28.547750131 +0200
+++ gcc/go/Make-lang.in	2014-09-12 11:25:50.271338395 +0200
@@ -131,11 +131,7 @@ go.srcman: doc/gccgo.1
 
 lang_checks += check-go
 lang_checks_parallelized += check-go
-check_go_parallelize = go-test.exp=*/test/\[0-57-9a-bd-hj-qs-zA-Z\]* \
-		       go-test.exp=*/test/c* \
-		       go-test.exp=*/test/i* \
-		       go-test.exp=*/test/r* \
-		       go-test.exp=*/test/6*
+check_go_parallelize = 10
 
 # Install hooks.
 
--- gcc/fortran/Make-lang.in.jj	2014-09-11 20:35:28.386750942 +0200
+++ gcc/fortran/Make-lang.in	2014-09-12 11:25:50.271338395 +0200
@@ -168,12 +168,7 @@ check-fortran-subtargets : check-gfortra
 lang_checks += check-gfortran
 lang_checks_parallelized += check-gfortran
 # For description see comment above check_gcc_parallelize in gcc/Makefile.in.
-check_gfortran_parallelize = dg.exp=gfortran.dg/\[adAD\]* \
-			     dg.exp=gfortran.dg/\[bcBC\]* \
-			     dg.exp=gfortran.dg/\[nopNOP\]* \
-			     dg.exp=gfortran.dg/\[isuvISUV\]* \
-			     dg.exp=gfortran.dg/\[efhkqrxzEFHKQRXZ\]* \
-			     dg.exp=gfortran.dg/\[0-9gjlmtwyGJLMTWY\]*
+check_gfortran_parallelize = 10000
 
 # GFORTRAN documentation.
 GFORTRAN_TEXI = \
--- gcc/cp/Make-lang.in.jj	2014-09-11 20:35:28.444750641 +0200
+++ gcc/cp/Make-lang.in	2014-09-12 11:25:50.273338382 +0200
@@ -156,11 +156,7 @@ check-c++-subtargets : check-g++-subtarg
 lang_checks += check-g++
 lang_checks_parallelized += check-g++
 # For description see comment above check_gcc_parallelize in gcc/Makefile.in.
-check_g++_parallelize = old-deja.exp \
-	dg.exp=g++.dg/[0-9A-Za-bd-su-z]* \
-	dg.exp=g++.dg/[ct]* \
-	dg.exp=c-c++-common/*,dg-torture.exp
-
+check_g++_parallelize = 10000
 #
 # Install hooks:
 # cc1plus is installed elsewhere as part of $(COMPILERS).
--- gcc/testsuite/g++.dg/guality/guality.exp.jj	2014-07-04 10:20:37.106214208 +0200
+++ gcc/testsuite/g++.dg/guality/guality.exp	2014-09-12 15:26:03.213193139 +0200
@@ -14,6 +14,11 @@ if { [istarget "powerpc-ibm-aix*"] } {
 }
 
 proc check_guality {args} {
+    # Don't count check_guality as PASS, or FAIL etc., that would make
+    # the total PASS count dependent on how many parallel runtest invocations
+    # ran guality.exp.  So save the counts first and restore them afterwards.
+    global test_counts
+    array set saved_test_counts [array get test_counts]
     set result [eval check_compile guality_check executable $args "-g -O0"]
     set lines [lindex $result 0]
     set output [lindex $result 1]
@@ -23,6 +28,7 @@ proc check_guality {args} {
       set ret [string match "*1 PASS, 0 FAIL, 0 UNRESOLVED*" $execout]
     }
     remote_file build delete $output
+    array get test_counts [array get saved_test_counts]
     return $ret
 }
 
--- gcc/testsuite/g++.dg/compat/struct-layout-1.exp	2014-09-12 11:25:50.294338271 +0200
+++ gcc/testsuite/g++.dg/compat/struct-layout-1.exp	2014-09-12 17:10:02.945849340 +0200
@@ -95,6 +95,15 @@
 
 g++_init
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p struct_layout_1] {
+    return
+}
+gcc_parallel_test_enable 0
+
 # Save variables for the C++ compiler under test, which each test will
 # change a couple of times.  This must be done after calling g++-init.
 set save_gxx_under_test $GXX_UNDER_TEST
@@ -170,0 +180,2 @@
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/g++.dg/plugin/plugin.exp	2014-09-12 11:25:50.294338271 +0200
+++ gcc/testsuite/g++.dg/plugin/plugin.exp	2014-09-12 17:11:56.292298712 +0200
@@ -44,6 +44,15 @@
 # Load support procs.
 load_lib plugin-support.exp
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p plugin] {
+    return
+}
+gcc_parallel_test_enable 0
+
 # Specify the plugin source file and the associated test files in a list.
 # plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
 set plugin_test_list [list \
@@ -70,0 +80,2 @@
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.dg/guality/guality.exp.jj	2014-07-04 10:20:36.000000000 +0200
+++ gcc/testsuite/gcc.dg/guality/guality.exp	2014-09-12 15:25:41.926294560 +0200
@@ -14,6 +14,11 @@ if { [istarget "powerpc-ibm-aix*"] } {
 }
 
 proc check_guality {args} {
+    # Don't count check_guality as PASS, or FAIL etc., that would make
+    # the total PASS count dependent on how many parallel runtest invocations
+    # ran guality.exp.  So save the counts first and restore them afterwards.
+    global test_counts
+    array set saved_test_counts [array get test_counts]
     set result [eval check_compile guality_check executable $args "-g -O0"]
     set lines [lindex $result 0]
     set output [lindex $result 1]
@@ -23,6 +28,7 @@ proc check_guality {args} {
       set ret [string match "*1 PASS, 0 FAIL, 0 UNRESOLVED*" $execout]
     }
     remote_file build delete $output
+    array set test_counts [array get saved_test_counts]
     return $ret
 }
 
--- gcc/testsuite/gcc.dg/compat/struct-layout-1.exp	2014-09-12 11:25:50.304338220 +0200
+++ gcc/testsuite/gcc.dg/compat/struct-layout-1.exp	2014-09-12 17:08:38.185257790 +0200
@@ -53,6 +53,15 @@
 
 gcc_init
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p struct_layout_1] {
+    return
+}
+gcc_parallel_test_enable 0
+
 # Save variables for the C compiler under test, which each test will
 # change a couple of times.  This must be done after calling gcc-init.
 set compat_save_gcc_under_test $GCC_UNDER_TEST
@@ -130,0 +140,2 @@
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.dg/plugin/plugin.exp	2014-09-12 11:25:50.304338220 +0200
+++ gcc/testsuite/gcc.dg/plugin/plugin.exp	2014-09-12 17:09:19.901057981 +0200
@@ -44,6 +44,15 @@
 # Load support procs.
 load_lib plugin-support.exp
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p plugin] {
+    return
+}
+gcc_parallel_test_enable 0
+
 # Specify the plugin source file and the associated test files in a list.
 # plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
 set plugin_test_list [list \
@@ -82,0 +92,2 @@
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/go.test/go-test.exp.jj	2014-08-01 09:23:38.000000000 +0200
+++ gcc/testsuite/go.test/go-test.exp	2014-09-12 11:39:15.712425307 +0200
@@ -489,6 +489,12 @@ proc go-gc-tests { } {
 
 	close $fd
 
+	# runtest_file_p is already run above, and the code below can run
+	# runtest_file_p again, make sure everything for this test is
+	# performed if the above runtest_file_p decided this runtest
+	# instance should execute the test
+	gcc_parallel_test_enable 0
+
 	set go_compile_args ""
 	set go_execute_args ""
 	if { [regexp "// run (\[^|&>2\].*)\$" $test_line match progargs] \
@@ -1164,6 +1170,7 @@ proc go-gc-tests { } {
 	set go_compile_args ""
 	set go_execute_args ""
         set TORTURE_OPTIONS [list { -O2 -g }]
+	gcc_parallel_test_enable 1
     }
 
     set dg-do-what-default ${saved-dg-do-what-default}
--- gcc/testsuite/lib/gcc-defs.exp.jj	2014-09-11 20:35:28.016752762 +0200
+++ gcc/testsuite/lib/gcc-defs.exp	2014-09-12 13:03:18.381369449 +0200
@@ -188,6 +188,77 @@ if { [info procs runtest_file_p] == "" }
     }
 }
 
+if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
+     && [info procs runtest_file_p] != [list] \
+     && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then {
+    global gcc_runtest_parallelize_counter
+    global gcc_runtest_parallelize_counter_minor
+    global gcc_runtest_parallelize_enable
+    global gcc_runtest_parallelize_dir
+    global gcc_runtest_parallelize_last
+
+    set gcc_runtest_parallelize_counter 0
+    set gcc_runtest_parallelize_counter_minor 0
+    set gcc_runtest_parallelize_enable 1
+    set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR]
+    set gcc_runtest_parallelize_last 0
+
+    proc gcc_parallel_test_run_p { testcase } {
+	global gcc_runtest_parallelize_counter
+	global gcc_runtest_parallelize_counter_minor
+	global gcc_runtest_parallelize_enable
+	global gcc_runtest_parallelize_dir
+	global gcc_runtest_parallelize_last
+
+	if { $gcc_runtest_parallelize_enable == 0 } {
+	    return 1
+	}
+
+	# Only test the filesystem every 10th iteration
+	incr gcc_runtest_parallelize_counter_minor
+	if { $gcc_runtest_parallelize_counter_minor == 10 } {
+	    set gcc_runtest_parallelize_counter_minor 0
+	}
+	if { $gcc_runtest_parallelize_counter_minor != 1 } {
+	    return $gcc_runtest_parallelize_last
+	}
+
+	set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter
+	incr gcc_runtest_parallelize_counter
+
+	if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} {
+	    close $fd
+	    set gcc_runtest_parallelize_last 1
+	    return 1
+	}
+	set gcc_runtest_parallelize_last 0
+	return 0
+    }
+
+    proc gcc_parallel_test_enable { val } {
+	global gcc_runtest_parallelize_enable
+	set gcc_runtest_parallelize_enable $val
+    }
+
+    rename runtest_file_p gcc_parallelize_saved_runtest_file_p
+    proc runtest_file_p { runtests testcase } {
+	if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] {
+	    return 0
+	}
+	return [gcc_parallel_test_run_p $testcase]
+    }
+
+} else {
+
+    proc gcc_parallel_test_run_p { testcase } {
+	return 1
+    }
+
+    proc gcc_parallel_test_enable { val } {
+    }
+
+}
+
 # Like dg-options, but adds to the default options rather than replacing them.
 
 proc dg-additional-options { args } {
--- gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp.jj	2014-09-11 20:35:28.329751198 +0200
+++ gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp	2014-09-12 11:25:50.318338150 +0200
@@ -28,6 +28,13 @@ if ![info exists DEFAULT_CFLAGS] then {
 # Initialize `dg'.
 dg-init
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if [gcc_parallel_test_run_p gnu_encoding] {
+gcc_parallel_test_enable 0
+
 #
 # gnu-encoding tests
 #
@@ -67,10 +74,8 @@ if { $status == 0 } then {
     warning "Could not compile objc.dg/gnu-encoding/struct-layout-encoding-1 generator"
 }
 
-
-
-
-
+gcc_parallel_test_enable 1
+}
 
 # All done.
 dg-finish
--- gcc/objc/Make-lang.in.jj	2014-09-11 20:35:28.499750358 +0200
+++ gcc/objc/Make-lang.in	2014-09-12 11:25:50.318338150 +0200
@@ -96,7 +96,7 @@ lang_checks += check-objc
 # The following allows you to do 'make check-objc -j2'.  The
 # execute.exp tests will be run in parallel with all the other ones.
 lang_checks_parallelized += check-objc
-check_objc_parallelize = gnu-encoding.exp execute.exp exceptions.exp
+check_objc_parallelize = 6
 
 #
 # Install hooks:
--- gcc/testsuite/gcc.misc-tests/matrix1.exp.jj	2014-01-03 11:40:43.400398937 +0100
+++ gcc/testsuite/gcc.misc-tests/matrix1.exp	2014-09-12 17:15:15.918325624 +0200
@@ -20,9 +20,21 @@ if { ![info exists PERF_TEST] || "$PERF_
 }
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p matrix1] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions run
 set compiler_output "^$"
 set program_output "^$"
 postbase matrix1.c $run $groups
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/dhry.exp.jj	2014-01-03 11:40:43.404398913 +0100
+++ gcc/testsuite/gcc.misc-tests/dhry.exp	2014-09-12 17:14:56.373426995 +0200
@@ -20,9 +20,21 @@ if { ![info exists PERF_TEST] || "$PERF_
 }
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p dhry] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions run
 set compiler_output "^$"
 set program_output "^$"
 postbase dhry.c $run $groups
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/acker1.exp.jj	2014-01-03 11:40:43.404398913 +0100
+++ gcc/testsuite/gcc.misc-tests/acker1.exp	2014-09-12 17:14:51.335450103 +0200
@@ -20,9 +20,21 @@ if { ![info exists PERF_TEST] || "$PERF_
 }
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p acker1] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions run
 set compiler_output "^$"
 set program_output "^$"
 postbase acker1.c $run $groups
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/linkage.exp.jj	2014-01-03 11:40:43.406398901 +0100
+++ gcc/testsuite/gcc.misc-tests/linkage.exp	2014-09-12 17:15:09.144367905 +0200
@@ -18,6 +18,17 @@
 # was written by Rob Savoye. (rob@cygnus.com)
 # All the other tests driven by that file have since been moved elsewhere.
 
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p linkage] {
+    return
+}
+gcc_parallel_test_enable 0
+
 if { [isnative] && ![is_remote host] } then {
     set lines [gcc_target_compile "$srcdir/$subdir/linkage-x.c" "linkage-x.o" object {additional_flags="-w"}]
     if ![string match "" $lines] then {
@@ -117,3 +128,5 @@ if { [isnative] && ![is_remote host] } t
 	file delete "linkage-x.o"
     }
 }
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/mg.exp.jj	2014-01-03 11:40:43.403398920 +0100
+++ gcc/testsuite/gcc.misc-tests/mg.exp	2014-09-12 17:15:25.406276624 +0200
@@ -17,8 +17,20 @@
 # Test the -MG flag.
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p mg] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions none-of-the-above
 set compiler_output "mg.o ?: .*mg.c \[ \\\\\n\]*nonexist.h"
 postbase mg.c "" "" "-MM -MG"
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/mg-2.exp.jj	2014-01-03 11:40:43.402398926 +0100
+++ gcc/testsuite/gcc.misc-tests/mg-2.exp	2014-09-12 17:15:20.466298272 +0200
@@ -17,8 +17,20 @@
 # Test the -MG flag with a system header file.
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p mg-2] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions none-of-the-above
 set compiler_output "mg-2.o ?: .*mg-2.c \[ \\\\\n\]*nonexist.h"
 postbase mg-2.c "" "" "-MM -MG"
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/sort2.exp.jj	2014-01-03 11:40:43.399398942 +0100
+++ gcc/testsuite/gcc.misc-tests/sort2.exp	2014-09-12 17:15:48.947116261 +0200
@@ -20,9 +20,21 @@ if { ![info exists PERF_TEST] || "$PERF_
 }
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p sort2] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions run
 set compiler_output "^$"
 set program_output "^$"
 postbase sort2.c $run $groups
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/sieve.exp.jj	2014-01-03 11:40:43.407398896 +0100
+++ gcc/testsuite/gcc.misc-tests/sieve.exp	2014-09-12 17:15:43.418154804 +0200
@@ -20,9 +20,21 @@ if { ![info exists PERF_TEST] || "$PERF_
 }
 
 load_lib mike-gcc.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p sieve] {
+    return
+}
+gcc_parallel_test_enable 0
 
 prebase
 set actions run
 set compiler_output "^$"
 set program_output "^$"
 postbase sieve.c $run $groups
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/options.exp.jj	2014-01-03 11:40:43.401398931 +0100
+++ gcc/testsuite/gcc.misc-tests/options.exp	2014-09-12 17:15:30.948230381 +0200
@@ -19,6 +19,17 @@
 # match the patterns COMPILER_PATTERN, AS_PATTERN and LD_PATTERN,
 # respectively.
 
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p options] {
+    return
+}
+gcc_parallel_test_enable 0
+
 proc check_for_all_options {language gcc_options compiler_pattern as_pattern ld_pattern} {
     set filename test-[pid]
     set fd [open $filename.c w]
@@ -52,3 +63,5 @@ proc check_for_all_options {language gcc
 }
 
 check_for_all_options c {--coverage} {-fprofile-arcs -ftest-coverage} {} {-lgcov}
+
+gcc_parallel_test_enable 1
--- gcc/testsuite/gcc.misc-tests/help.exp.jj	2014-01-03 11:40:43.400398937 +0100
+++ gcc/testsuite/gcc.misc-tests/help.exp	2014-09-12 17:15:02.997394449 +0200
@@ -18,6 +18,16 @@
 # documented in --help, and that the various --help* options work.
 
 load_lib options.exp
+load_lib gcc-defs.exp
+
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p help] {
+    return
+}
+gcc_parallel_test_enable 0
 
 # Document --version.  Ideally, there should be no undocumented switches
 # in --help.
@@ -78,3 +88,5 @@ check_for_options c "--help=joined,^sepa
 check_for_options c "--help=joined,undocumented" "" "" ""
 # Listing only excludes gives empty results.
 check_for_options c "--help=^joined,^separate" "" "" ""
+
+gcc_parallel_test_enable 1
--- libstdc++-v3/testsuite/Makefile.am.jj	2014-01-03 11:42:07.000000000 +0100
+++ libstdc++-v3/testsuite/Makefile.am	2014-09-12 16:20:35.687366456 +0200
@@ -101,7 +101,16 @@ new-abi-baseline:
 	@test ! -f $*/site.exp || mv $*/site.exp $*/site.bak
 	@mv $*/site.exp.tmp $*/site.exp
 
-check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9 10)
+check_p_numbers0:=1 2 3 4 5 6 7 8 9
+check_p_numbers1:=0 $(check_p_numbers0)
+check_p_numbers2:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers1)))
+check_p_numbers3:=$(patsubst %,0%,$(check_p_numbers1)) $(check_p_numbers2)
+check_p_numbers4:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers3)))
+check_p_numbers5:=$(patsubst %,0%,$(check_p_numbers3)) $(check_p_numbers4)
+check_p_numbers6:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers5)))
+check_p_numbers:=$(check_p_numbers0) $(check_p_numbers2) $(check_p_numbers4) $(check_p_numbers6)
+check_p_subdirs=$(wordlist 1,$(or $(GCC_TEST_PARALLEL_SLOTS),128),$(check_p_numbers))
+check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,$(check_p_subdirs))
 $(check_DEJAGNU_normal_targets): check-DEJAGNUnormal%: normal%/site.exp
 
 # Run the testsuite in normal mode.
@@ -110,10 +119,15 @@ check-DEJAGNU $(check_DEJAGNU_normal_tar
 	RANLIB="$(RANLIB)"; export RANLIB; \
 	if [ -z "$*$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \
 	    && [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
+	  rm -rf normal-parallel || true; \
+	  mkdir normal-parallel; \
 	  $(MAKE) $(AM_MAKEFLAGS) $(check_DEJAGNU_normal_targets); \
-	  for idx in 0 1 2 3 4 5 6 7 8 9 10; do \
-	    mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
-	    mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
+	  rm -rf normal-parallel || true; \
+	  for idx in $(check_p_subdirs); do \
+	    if [ -d normal$$idx ]; then \
+	      mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
+	      mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
+	    fi; \
 	  done; \
 	  mv -f libstdc++.sum libstdc++.sum.sep; \
 	  mv -f libstdc++.log libstdc++.log.sep; \
@@ -128,47 +142,30 @@ check-DEJAGNU $(check_DEJAGNU_normal_tar
 	runtest=$(RUNTEST); \
 	if [ -z "$$runtest" ]; then runtest=runtest; fi; \
 	tool=libstdc++; \
-	dirs=; \
-	case "$*" in \
-	  normal0) \
-	    if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
-	      $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-			$(RUNTESTFLAGS) abi.exp prettyprinters.exp; \
-	    else echo "WARNING: could not find \`runtest'" 1>&2; :;\
-	    fi; \
-	    dirs="`cd $$srcdir; echo [013-9][0-9]_*/*`";; \
-	  normal1) \
-	    dirs="`cd $$srcdir; echo [ab]* de* [ep]*/*`";; \
-	  normal2) \
-	    dirs="`cd $$srcdir; echo 2[01]_*/*`";; \
-	  normal3) \
-	    dirs="`cd $$srcdir; echo 22_*/*`";; \
-	  normal4) \
-	    dirs="`cd $$srcdir; echo 23_*/[a-km-tw-z]*`";; \
-	  normal5) \
-	    dirs="`cd $$srcdir; echo 23_*/[luv]*`";; \
-	  normal6) \
-	    dirs="`cd $$srcdir; echo 2[459]_*/*`";; \
-	  normal7) \
-	    dirs="`cd $$srcdir; echo 26_*/* 28_*/[c-z]*`";; \
-	  normal8) \
-	    dirs="`cd $$srcdir; echo 27_*/*`";; \
-	  normal9) \
-	    dirs="`cd $$srcdir; echo 28_*/[ab]*`";; \
-	  normal10) \
-	    dirs="`cd $$srcdir; echo t*/*`";; \
-	esac; \
-	if [ -n "$*" ]; then cd "$*"; fi; \
-	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
-	  if [ -n "$$dirs" ]; then \
+	runtestargs=; \
+	if [ "$*" = normal1 ]; then \
+	  if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
 	    $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-		    $(RUNTESTFLAGS) \
-		    "conformance.exp=`echo $$dirs | sed 's/ /* /g;s/$$/*/'`"; \
+		      $(RUNTESTFLAGS) abi.exp prettyprinters.exp; \
 	  else \
-	    $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-		    $(RUNTESTFLAGS); \
+	    echo "WARNING: could not find \`runtest'" 1>&2; :; \
+	  fi; \
+	fi; \
+	if [ -n "$*" ]; then \
+	  if [ -f normal-parallel/finished ]; then rm -rf "$*"; exit 0; fi; \
+	  GCC_RUNTEST_PARALLELIZE_DIR=`${PWD_COMMAND}`/normal-parallel; \
+	  export GCC_RUNTEST_PARALLELIZE_DIR; \
+	  cd "$*"; \
+	  runtestargs=conformance.exp; \
+	fi; \
+	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+	  $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
+		    $(RUNTESTFLAGS) $$runtestargs; \
+	  if [ -n "$*" ]; then \
+	    touch $$GCC_RUNTEST_PARALLELIZE_DIR/finished; \
 	  fi; \
-	else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+	else \
+	  echo "WARNING: could not find \`runtest'" 1>&2; :;\
 	fi
 
 check-am:
--- libstdc++-v3/testsuite/Makefile.in.jj	2013-11-22 21:38:38.653239025 +0100
+++ libstdc++-v3/testsuite/Makefile.in	2014-09-12 16:21:04.201235261 +0200
@@ -301,7 +301,16 @@ lists_of_files = \
 
 extract_symvers = $(glibcxx_builddir)/scripts/extract_symvers
 baseline_subdir := $(shell $(CXX) $(baseline_subdir_switch))
-check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9 10)
+check_p_numbers0:=1 2 3 4 5 6 7 8 9
+check_p_numbers1:=0 $(check_p_numbers0)
+check_p_numbers2:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers1)))
+check_p_numbers3:=$(patsubst %,0%,$(check_p_numbers1)) $(check_p_numbers2)
+check_p_numbers4:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers3)))
+check_p_numbers5:=$(patsubst %,0%,$(check_p_numbers3)) $(check_p_numbers4)
+check_p_numbers6:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers5)))
+check_p_numbers:=$(check_p_numbers0) $(check_p_numbers2) $(check_p_numbers4) $(check_p_numbers6)
+check_p_subdirs=$(wordlist 1,$(or $(GCC_TEST_PARALLEL_SLOTS),128),$(check_p_numbers))
+check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,$(check_p_subdirs))
 
 # Runs the testsuite, but in compile only mode.
 # Can be used to test sources with non-GNU FE's at various warning
@@ -561,10 +570,15 @@ check-DEJAGNU $(check_DEJAGNU_normal_tar
 	RANLIB="$(RANLIB)"; export RANLIB; \
 	if [ -z "$*$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \
 	    && [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
+	  rm -rf normal-parallel || true; \
+	  mkdir normal-parallel; \
 	  $(MAKE) $(AM_MAKEFLAGS) $(check_DEJAGNU_normal_targets); \
-	  for idx in 0 1 2 3 4 5 6 7 8 9 10; do \
-	    mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
-	    mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
+	  rm -rf normal-parallel || true; \
+	  for idx in $(check_p_subdirs); do \
+	    if [ -d normal$$idx ]; then \
+	      mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
+	      mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
+	    fi; \
 	  done; \
 	  mv -f libstdc++.sum libstdc++.sum.sep; \
 	  mv -f libstdc++.log libstdc++.log.sep; \
@@ -579,47 +593,30 @@ check-DEJAGNU $(check_DEJAGNU_normal_tar
 	runtest=$(RUNTEST); \
 	if [ -z "$$runtest" ]; then runtest=runtest; fi; \
 	tool=libstdc++; \
-	dirs=; \
-	case "$*" in \
-	  normal0) \
-	    if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
-	      $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-			$(RUNTESTFLAGS) abi.exp prettyprinters.exp; \
-	    else echo "WARNING: could not find \`runtest'" 1>&2; :;\
-	    fi; \
-	    dirs="`cd $$srcdir; echo [013-9][0-9]_*/*`";; \
-	  normal1) \
-	    dirs="`cd $$srcdir; echo [ab]* de* [ep]*/*`";; \
-	  normal2) \
-	    dirs="`cd $$srcdir; echo 2[01]_*/*`";; \
-	  normal3) \
-	    dirs="`cd $$srcdir; echo 22_*/*`";; \
-	  normal4) \
-	    dirs="`cd $$srcdir; echo 23_*/[a-km-tw-z]*`";; \
-	  normal5) \
-	    dirs="`cd $$srcdir; echo 23_*/[luv]*`";; \
-	  normal6) \
-	    dirs="`cd $$srcdir; echo 2[459]_*/*`";; \
-	  normal7) \
-	    dirs="`cd $$srcdir; echo 26_*/* 28_*/[c-z]*`";; \
-	  normal8) \
-	    dirs="`cd $$srcdir; echo 27_*/*`";; \
-	  normal9) \
-	    dirs="`cd $$srcdir; echo 28_*/[ab]*`";; \
-	  normal10) \
-	    dirs="`cd $$srcdir; echo t*/*`";; \
-	esac; \
-	if [ -n "$*" ]; then cd "$*"; fi; \
-	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
-	  if [ -n "$$dirs" ]; then \
+	runtestargs=; \
+	if [ "$*" = normal1 ]; then \
+	  if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
 	    $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-		    $(RUNTESTFLAGS) \
-		    "conformance.exp=`echo $$dirs | sed 's/ /* /g;s/$$/*/'`"; \
+		      $(RUNTESTFLAGS) abi.exp prettyprinters.exp; \
 	  else \
-	    $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
-		    $(RUNTESTFLAGS); \
+	    echo "WARNING: could not find \`runtest'" 1>&2; :; \
+	  fi; \
+	fi; \
+	if [ -n "$*" ]; then \
+	  if [ -f normal-parallel/finished ]; then rm -rf "$*"; exit 0; fi; \
+	  GCC_RUNTEST_PARALLELIZE_DIR=`${PWD_COMMAND}`/normal-parallel; \
+	  export GCC_RUNTEST_PARALLELIZE_DIR; \
+	  cd "$*"; \
+	  runtestargs=conformance.exp; \
+	fi; \
+	if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+	  $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) \
+		    $(RUNTESTFLAGS) $$runtestargs; \
+	  if [ -n "$*" ]; then \
+	    touch $$GCC_RUNTEST_PARALLELIZE_DIR/finished; \
 	  fi; \
-	else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+	else \
+	  echo "WARNING: could not find \`runtest'" 1>&2; :;\
 	fi
 
 check-am:
--- libstdc++-v3/testsuite/lib/libstdc++.exp.jj	2014-07-14 09:30:36.000000000 +0200
+++ libstdc++-v3/testsuite/lib/libstdc++.exp	2014-09-12 16:06:40.415394092 +0200
@@ -1823,3 +1823,74 @@ proc check_v3_target_little_endian { } {
 }
 
 set additional_prunes ""
+
+if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
+     && [info procs runtest_file_p] != [list] \
+     && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then {
+    global gcc_runtest_parallelize_counter
+    global gcc_runtest_parallelize_counter_minor
+    global gcc_runtest_parallelize_enable
+    global gcc_runtest_parallelize_dir
+    global gcc_runtest_parallelize_last
+
+    set gcc_runtest_parallelize_counter 0
+    set gcc_runtest_parallelize_counter_minor 0
+    set gcc_runtest_parallelize_enable 1
+    set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR]
+    set gcc_runtest_parallelize_last 0
+
+    proc gcc_parallel_test_run_p { testcase } {
+	global gcc_runtest_parallelize_counter
+	global gcc_runtest_parallelize_counter_minor
+	global gcc_runtest_parallelize_enable
+	global gcc_runtest_parallelize_dir
+	global gcc_runtest_parallelize_last
+
+	if { $gcc_runtest_parallelize_enable == 0 } {
+	    return 1
+	}
+
+	# Only test the filesystem every 10th iteration
+	incr gcc_runtest_parallelize_counter_minor
+	if { $gcc_runtest_parallelize_counter_minor == 10 } {
+	    set gcc_runtest_parallelize_counter_minor 0
+	}
+	if { $gcc_runtest_parallelize_counter_minor != 1 } {
+	    return $gcc_runtest_parallelize_last
+	}
+
+	set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter
+	incr gcc_runtest_parallelize_counter
+
+	if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} {
+	    close $fd
+	    set gcc_runtest_parallelize_last 1
+	    return 1
+	}
+	set gcc_runtest_parallelize_last 0
+	return 0
+    }
+
+    proc gcc_parallel_test_enable { val } {
+	global gcc_runtest_parallelize_enable
+	set gcc_runtest_parallelize_enable $val
+    }
+
+    rename runtest_file_p gcc_parallelize_saved_runtest_file_p
+    proc runtest_file_p { runtests testcase } {
+	if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] {
+	    return 0
+	}
+	return [gcc_parallel_test_run_p $testcase]
+    }
+
+} else {
+
+    proc gcc_parallel_test_run_p { testcase } {
+	return 1
+    }
+
+    proc gcc_parallel_test_enable { val } {
+    }
+
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]