]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Reduce overhead of tests/wrapper.as zack/perl-interp-overhead
authorZack Weinberg <zack@owlfolio.org>
Thu, 7 Dec 2023 19:06:26 +0000 (14:06 -0500)
committerZack Weinberg <zack@owlfolio.org>
Thu, 7 Dec 2023 19:06:26 +0000 (14:06 -0500)
tests/wrapper.as is a wrapper script that enables the test suite to
run Autoconf’s command line tools (autoconf, autoheader, etc.) without
having installed them first.  It’s written in m4sh.  All of the
programs it wraps are written in Perl.  Therefore, we can make the
wrapper more efficient by rewriting it in Perl and having it invoke
the real program with the ‘do’ builtin.  This cuts out the cost of
starting up a shell and crunching through m4sh initialization (order
of 400 lines of code).  Using ‘do’ means we only have to start up Perl
once.

‘make check TESTSUITEFLAGS="-j24"’ speeds up a small but consistently
measurable amount on my workstation.  The wall-clock time difference
would be bigger at lower levels of parallelism.

before:
wall    1m16.716s
user    16m44.847s
sys     12m6.452s

                 wall     user    sys    user+sys
autom4te         451.16   261.75  35.75  297.5
autoheader       188.9    42.54   6.1    48.64
autoupdate       47.25    5.39    0.73   6.12
autoreconf       35.68    1.66    0.28   1.94
autoscan         0.88     0.31    0.04   0.35
ifnames          0.25     0.2     0.02   0.22
autoconf         0.18     0.13    0.01   0.14

after:
wall    1m14.624s
user    16m21.883s
sys     11m37.521s

                 wall     user    sys    user+sys
autom4te         415.49   256.41  27.83  284.24
autoheader       170.87   40.97   3.94   44.91
autoupdate       44.7     5.26    0.59   5.85
autoreconf       33.42    1.54    0.13   1.67
autoscan         0.76     0.27    0.03   0.3
ifnames          0.21     0.18    0      0.18
autoconf         0.14     0.11    0      0.11

(Total time per program collected using BSD process accounting.)

bin/autoconf.in
bin/autoheader.in
bin/ifnames.in
lib/Autom4te/FileUtils.pm
tests/local.at
tests/local.mk
tests/tools.at
tests/wrapper.as [deleted file]
tests/wrapper.in [new file with mode: 0755]

index 060a9a04f4102e172214d9f77c67cd05606a4146..aed395ea192b4dd65b91aa333d2cf5c6e5d885b0 100644 (file)
@@ -193,7 +193,8 @@ print {*STDERR} $me,
   "\n"
   if $verbose;
 
-exec {$autom4te_command[0]} @autom4te_command;
+exec {$autom4te_command[0]} @autom4te_command
+  or fatal "$autom4te_command[0]: $!\n";
 
 ### Setup "GNU" style for perl-mode and cperl-mode.
 ## Local Variables:
index 4afa5f1383417f6063873d60c0c7f548a1994a1f..8c08a66d18d3927ab759a012e19b176f3656e0ff 100644 (file)
@@ -314,6 +314,7 @@ $out->close;
 }
 
 update_file ("$tmp/config.hin", "$config_h_in", $force);
+exit 0;
 
 ### Setup "GNU" style for perl-mode and cperl-mode.
 ## Local Variables:
index 2626b167b4d472c76abe52c46e6b90edc5fc8a9f..dd06410db3fb80ee5f5eafe6490b831c52332e67 100644 (file)
@@ -138,6 +138,7 @@ foreach (sort keys %occurrence)
   {
     print "$_ ", join (' ', sort keys %{$occurrence{$_}}), "\n";
   }
+exit 0;
 
 ### Setup "GNU" style for perl-mode and cperl-mode.
 ## Local Variables:
index 06f87c31a3cde628a2dacb79135ece93c03e2a82..b7cc99ac8d170eab9c49e80a36ae622e1be14eb6 100644 (file)
@@ -186,7 +186,7 @@ sub update_file ($$;$)
       msg 'note', "'$to' is unchanged";
       unlink ($from)
         or fatal "cannot remove $from: $!";
-      return
+      return;
     }
 
   if (-f "$to")
index a5de5e145dac36520a9a9c6394200b542f473263..0e278019217c085223492d81f1b88cff0bc79a22 100644 (file)
@@ -159,7 +159,7 @@ m4_define([AT_CHECK_SHELL_SYNTAX],
 AT_CHECK(["$SHELL_N" -n $1], [], [], [ignore])])
 
 m4_define([AT_CHECK_PERL_SYNTAX],
-[AT_CHECK([autom4te_perllibdir=$abs_top_srcdir/lib $PERL -c "$abs_top_builddir"/bin/$1],
+[AT_CHECK([autom4te_perllibdir=$abs_top_srcdir/lib $PERL -c "$abs_top_builddir/$1"],
           0, [], [ignore])])
 
 ## ------------------ ##
index c100f0c12c2c57e8c7b0b6362ebe997ce8c4eef0..ae399c4d121cca9e5d01a9fdac03fd12baec5c7d 100644 (file)
@@ -23,7 +23,7 @@ EXTRA_DIST += \
   tests/local.at \
   tests/mktests.pl \
   tests/atlocal.in \
-  tests/wrapper.as \
+  tests/wrapper.in \
   tests/statesave.m4
 
 # Running the uninstalled scripts.  Build them upon 'all', for the manpages.
@@ -60,13 +60,10 @@ wrappers = \
 
 CLEANFILES += \
   tests/package.m4 \
-  tests/wrapper.in \
   $(wrappers)
 
-tests/wrapper.in: $(srcdir)/tests/wrapper.as $(m4sh_m4f_dependencies)
-       $(MY_AUTOM4TE) --language=M4sh $(srcdir)/tests/wrapper.as -o $@
-
 edit_wrapper = sed \
+       -e 's|@PERL[@]|$(PERL)|g' \
        -e 's|@wrap_program[@]|$(@F)|g' \
        -e 's|@abs_top_srcdir[@]|$(abs_top_srcdir)|g' \
        -e 's|@abs_top_builddir[@]|$(abs_top_builddir)|g' \
@@ -75,7 +72,7 @@ edit_wrapper = sed \
 $(wrappers): tests/wrapper.in
        rm -f $@ $@.tmp
        input=tests/wrapper.in \
-         && $(edit_wrapper) tests/wrapper.in >$@.tmp
+         && $(edit_wrapper) $(srcdir)/tests/wrapper.in >$@.tmp
        chmod +x $@.tmp
        chmod a-w $@.tmp
        mv -f $@.tmp $@
index 5dcf5f29fd8527849c9104e5b9e92525ae52a477..96381f74013bd2539474c9f8b4d91910ae554a49 100644 (file)
@@ -50,7 +50,6 @@ AT_CHECK([test "$SHELL_N" != none || exit 77])
 # Specify the absolute name of the tool, as some shells don't honor PATH when
 # running 'sh PROG'.
 
-AT_CHECK_SHELL_SYNTAX(["$abs_top_builddir/tests/autoconf"])
 AT_CHECK_SHELL_SYNTAX(["$abs_top_builddir/tests/testsuite"])
 
 # These are not built, they are in the src tree.
@@ -68,13 +67,21 @@ AT_CLEANUP
 
 AT_SETUP([Syntax of the Perl scripts])
 
-AT_CHECK_PERL_SYNTAX([autoconf])
-AT_CHECK_PERL_SYNTAX([autoheader])
-AT_CHECK_PERL_SYNTAX([autom4te])
-AT_CHECK_PERL_SYNTAX([autoreconf])
-AT_CHECK_PERL_SYNTAX([autoscan])
-AT_CHECK_PERL_SYNTAX([autoupdate])
-AT_CHECK_PERL_SYNTAX([ifnames])
+AT_CHECK_PERL_SYNTAX([bin/autoconf])
+AT_CHECK_PERL_SYNTAX([bin/autoheader])
+AT_CHECK_PERL_SYNTAX([bin/autom4te])
+AT_CHECK_PERL_SYNTAX([bin/autoreconf])
+AT_CHECK_PERL_SYNTAX([bin/autoscan])
+AT_CHECK_PERL_SYNTAX([bin/autoupdate])
+AT_CHECK_PERL_SYNTAX([bin/ifnames])
+
+AT_CHECK_PERL_SYNTAX([tests/autoconf])
+AT_CHECK_PERL_SYNTAX([tests/autoheader])
+AT_CHECK_PERL_SYNTAX([tests/autom4te])
+AT_CHECK_PERL_SYNTAX([tests/autoreconf])
+AT_CHECK_PERL_SYNTAX([tests/autoscan])
+AT_CHECK_PERL_SYNTAX([tests/autoupdate])
+AT_CHECK_PERL_SYNTAX([tests/ifnames])
 
 AT_CLEANUP
 
diff --git a/tests/wrapper.as b/tests/wrapper.as
deleted file mode 100644 (file)
index 4ffbc43..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-AS_INIT[]dnl                                            -*- shell-script -*-
-# wrapper.as -- running '@wrap_program@' as if it were installed.
-# @configure_input@
-# Copyright (C) 2003-2004, 2007, 2009-2017, 2020-2023 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 <https://www.gnu.org/licenses/>.
-
-testdir='@abs_top_builddir@/tests'
-PATH=$testdir$PATH_SEPARATOR$PATH
-AUTOCONF=autoconf
-AUTOHEADER=autoheader
-AUTOM4TE=autom4te
-AUTOM4TE_CFG='@abs_top_builddir@/lib/autom4te.cfg'
-autom4te_buildauxdir='@abs_top_srcdir@/build-aux'
-autom4te_perllibdir='@abs_top_srcdir@/lib'
-trailer_m4='@abs_top_srcdir@/lib/autoconf/trailer.m4'
-export AUTOCONF AUTOHEADER AUTOM4TE AUTOM4TE_CFG
-export autom4te_buildauxdir autom4te_perllibdir trailer_m4
-
-case '@wrap_program@' in
-  ifnames)
-     # Does not have lib files.
-     exec '@abs_top_builddir@/bin/@wrap_program@' ${1+"$@"}
-     ;;
-  *)
-     # We might need files from the build tree (frozen files), in
-     # addition of src files.
-     exec '@abs_top_builddir@/bin/@wrap_program@' \
-         -B '@abs_top_builddir@'/lib \
-         -B '@abs_top_srcdir@'/lib ${1+"$@"}
-esac
-exit 1
diff --git a/tests/wrapper.in b/tests/wrapper.in
new file mode 100755 (executable)
index 0000000..068fe39
--- /dev/null
@@ -0,0 +1,80 @@
+#! @PERL@
+# wrapper.in -- running '@wrap_program@' as if it were installed.
+# @configure_input@
+# Copyright (C) 2003-2004, 2007, 2009-2017, 2020-2023 Free Software
+# Foundation, Inc.
+
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+  if 0;
+
+# 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 <https://www.gnu.org/licenses/>.
+
+use 5.006;
+use strict;
+use warnings FATAL => 'all';
+
+my $src_libdir               = '@abs_top_srcdir@/lib';
+$ENV{'autom4te_perllibdir'}  = $src_libdir;
+$ENV{'autom4te_buildauxdir'} = '@abs_top_srcdir@/build-aux';
+$ENV{'trailer_m4'}           = '@abs_top_srcdir@/lib/autoconf/trailer.m4';
+
+my $wrapped_program          = '@wrap_program@';
+my $abs_wrapped_program      = '@abs_top_builddir@/bin/@wrap_program@';
+my $build_testdir            = '@abs_top_builddir@/tests';
+my $build_libdir             = '@abs_top_builddir@/lib';
+$ENV{'AUTOM4TE_CFG'}         = '@abs_top_builddir@/lib/autom4te.cfg';
+
+$ENV{'AUTOCONF'}             = 'autoconf';
+$ENV{'AUTOHEADER'}           = 'autoheader';
+$ENV{'AUTOM4TE'}             = 'autom4te';
+
+# Prepend $build_testdir to the path if it isn't there already.
+if (!defined $ENV{'PATH'} || $ENV{'PATH'} eq '')
+{
+  $ENV{'PATH'} = $build_testdir;
+}
+elsif ($ENV{'PATH'} !~ /^\Q$build_testdir\E[\\\/]?(?:[:;]|$)/)
+{
+  no warnings 'once';
+  require Config;
+  $ENV{'PATH'} = $build_testdir . $Config::Config{'path_sep'} . $ENV{'PATH'};
+}
+
+# All the wrapped programs *except* ifnames might need to load
+# .m4 and .m4f files from both the build and source libdirs.
+unshift (@ARGV, '-B', $build_libdir, '-B', $src_libdir)
+  if $wrapped_program ne 'ifnames';
+
+my $status = do $abs_wrapped_program;
+exit $status if defined $status;
+die "couldn't parse ${wrapped_program}: $@\n" if $@;
+die "error reading ${wrapped_program}: $!\n";
+
+### Setup "GNU" style for perl-mode and cperl-mode.
+## Local Variables:
+## mode: perl
+## perl-indent-level: 2
+## perl-continued-statement-offset: 2
+## perl-continued-brace-offset: 0
+## perl-brace-offset: 0
+## perl-brace-imaginary-offset: 0
+## perl-label-offset: -2
+## cperl-indent-level: 2
+## cperl-brace-offset: 0
+## cperl-continued-brace-offset: 0
+## cperl-label-offset: -2
+## cperl-extra-newline-before-brace: t
+## cperl-merge-trailing-else: nil
+## cperl-continued-statement-offset: 2
+## End: