From: Zack Weinberg Date: Thu, 7 Dec 2023 19:06:26 +0000 (-0500) Subject: Reduce overhead of tests/wrapper.as X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fzack%2Fperl-interp-overhead;p=thirdparty%2Fautoconf.git Reduce overhead of tests/wrapper.as 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.) --- diff --git a/bin/autoconf.in b/bin/autoconf.in index 060a9a04..aed395ea 100644 --- a/bin/autoconf.in +++ b/bin/autoconf.in @@ -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: diff --git a/bin/autoheader.in b/bin/autoheader.in index 4afa5f13..8c08a66d 100644 --- a/bin/autoheader.in +++ b/bin/autoheader.in @@ -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: diff --git a/bin/ifnames.in b/bin/ifnames.in index 2626b167..dd06410d 100644 --- a/bin/ifnames.in +++ b/bin/ifnames.in @@ -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: diff --git a/lib/Autom4te/FileUtils.pm b/lib/Autom4te/FileUtils.pm index 06f87c31..b7cc99ac 100644 --- a/lib/Autom4te/FileUtils.pm +++ b/lib/Autom4te/FileUtils.pm @@ -186,7 +186,7 @@ sub update_file ($$;$) msg 'note', "'$to' is unchanged"; unlink ($from) or fatal "cannot remove $from: $!"; - return + return; } if (-f "$to") diff --git a/tests/local.at b/tests/local.at index a5de5e14..0e278019 100644 --- a/tests/local.at +++ b/tests/local.at @@ -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])]) ## ------------------ ## diff --git a/tests/local.mk b/tests/local.mk index c100f0c1..ae399c4d 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -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 $@ diff --git a/tests/tools.at b/tests/tools.at index 5dcf5f29..96381f74 100644 --- a/tests/tools.at +++ b/tests/tools.at @@ -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 index 4ffbc436..00000000 --- a/tests/wrapper.as +++ /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 . - -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 index 00000000..068fe393 --- /dev/null +++ b/tests/wrapper.in @@ -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 . + +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: