[bug#71652] optimizing the sleep in Automake's sanity.m4

Karl Berry <[email protected]> Wed, 19 Jun 2024 10:26:43 -0600
Newsgroups gmane.comp.sysutils.automake.patches
Message-ID <[email protected]>
I'd like to have further discussion about this ongoing subject here,
for the sake of future trackability.

So far as I can see, we've currently got Bruno's patch#2 from
  https://lists.gnu.org/archive/html/automake/2024-06/msg00055.html
(attached here)


plus Nick's change to use AC_CONFIG_COMMANDS_POST instead of _PRE,
copied below, plus some sort of limiting. --thanks, karl.

Date: Mon, 17 Jun 2024 00:29:07 -0400
From: Nick Bowler <[email protected]>
Subject: Re: 1.16.90 regression: configure now takes 7 seconds to start

If the problem is simply that we want to avoid the situation where
"make" considers config.status to be out of date wrt. configure, or
something similar with any other pair of files, then this should be
solveable fairly easily with a pattern like this (but see below):

  AC_CONFIG_COMMANDS_POST([cat >conftest.mk <<'EOF'
  configure: config.status
  	false
  EOF
  while ${MAKE-make} -f conftest.mk >/dev/null 2>&1
  do
    touch config.status
  done])

In my own experience the above pattern is portable.  It works with HP-UX
make.  It works with a "touch" that truncates timestamps.  In the common
case where configure is sufficiently old the loop condition will always
be false and there is no delay.

It won't guarantee that config.status has a strictly newer timestamp
than configure (except on HP-UX), but it sounds like that's fine.

One missing element is that there is no limit, which would be a bit of a
problem if the clock skew is severe (e.g., if configure's mtime is years
or even minutes in the future), so something extra is probably desirable
to bound the amount of time this runs to something practical.
0001-automake-Save-up-to-2-seconds-of-configure-time.patch (application/octet-stream, 3.9 KB)
>From f8135b06c1a46228d974ec8edb1e928f8117d6e4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 13 Jun 2024 13:47:49 +0200
Subject: [PATCH] automake: Save up to 2 seconds of configure time.

* m4/sanity.m4 (AM_FILESYSTEM_TIMESTAMP_RESOLUTION): Renamed from
_AM_FILESYSTEM_TIMESTAMP_RESOLUTION. Suggested by Karl Berry.
(AM_SANITY_CHECK): Don't require
_AM_FILESYSTEM_TIMESTAMP_RESOLUTION. Instead, execute it only when it is
actually needed. In most cases outside Automake's test suite, it is not
needed. Also, omit the parallel sleep.
* configure.ac: Invoke AM_FILESYSTEM_TIMESTAMP_RESOLUTION.
---
 configure.ac |  1 +
 m4/sanity.m4 | 30 +++++++++++-------------------
 2 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3ff08e9f2..082d8bddb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,6 +190,7 @@ AC_PROG_FGREP
 # The test suite needs to know the resolution of timestamps
 # supported by the filesystem hosting the build.  The value
 # will be acceptable to 'sleep' on this system.
+AM_FILESYSTEM_TIMESTAMP_RESOLUTION
 MTIME_RESOLUTION=$am_cv_filesystem_timestamp_resolution
 if test -z "$MTIME_RESOLUTION"; then
   AC_MSG_NOTICE(am_cv_filesystem_timestamp_resolution strangely not set; using 1)
diff --git a/m4/sanity.m4 b/m4/sanity.m4
index 68fbf36f7..a8c6ff917 100644
--- a/m4/sanity.m4
+++ b/m4/sanity.m4
@@ -15,7 +15,7 @@ AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=true],
                                  [am_cv_sleep_fractional_seconds=false])
 ])])
 
-# _AM_FILESYSTEM_TIMESTAMP_RESOLUTION
+# AM_FILESYSTEM_TIMESTAMP_RESOLUTION
 # -----------------------------------
 # Determine the filesystem's resolution for file modification
 # timestamps.  The coarsest we know of is FAT, with a resolution
@@ -25,7 +25,7 @@ AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=true],
 # possible to delay execution of a shell script for less than one
 # millisecond, due to process creation overhead and scheduling
 # granularity, so we don't check for anything finer than that. (See below.)
-AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl
+AC_DEFUN([AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl
 AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS])
 AC_CACHE_CHECK([filesystem timestamp resolution],
                am_cv_filesystem_timestamp_resolution, [dnl
@@ -141,7 +141,7 @@ rm -f conftest.ts?
 # AM_SANITY_CHECK
 # ---------------
 AC_DEFUN([AM_SANITY_CHECK],
-[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION])
+[
 # This check should not be cached, as it may vary across builds of
 # different projects.
 AC_MSG_CHECKING([whether build environment is sane])
@@ -179,6 +179,14 @@ for am_try in 1 2; do
     am_build_env_is_sane=yes
     break
   fi
+  # Determine am_cv_filesystem_timestamp_resolution. Do it only on the first
+  # loop round, since it is expensive. Do so without visible output, because
+  # we're already in a AC_MSG_CHECKING..AC_MSG_RESULT block.
+  if test $am_try = 1; then
+    exec 9>&AS_MESSAGE_FD AS_MESSAGE_FD>/dev/null
+    AM_FILESYSTEM_TIMESTAMP_RESOLUTION
+    exec AS_MESSAGE_FD>&9 9>&-
+  fi
   # Just in case.
   sleep $am_cv_filesystem_timestamp_resolution
   am_has_slept=yes
@@ -189,20 +197,4 @@ if test $am_build_env_is_sane = no; then
   AC_MSG_ERROR([newly created file is older than distributed files!
 Check your system clock])
 fi
-
-# If we didn't sleep, we still need to ensure time stamps of config.status and
-# generated files are strictly newer.
-am_sleep_pid=
-AS_IF([test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1],, [dnl
-  ( sleep $am_cv_filesystem_timestamp_resolution ) &
-  am_sleep_pid=$!
-])
-AC_CONFIG_COMMANDS_PRE(
-  [AC_MSG_CHECKING([that generated files are newer than configure])
-   if test -n "$am_sleep_pid"; then
-     # Hide warnings about reused PIDs.
-     wait $am_sleep_pid 2>/dev/null
-   fi
-   AC_MSG_RESULT([done])])
-rm -f conftest.file
 ])
-- 
2.34.1