automake-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[automake-commit] branch master updated: m4: speed up filesystem modific


From: Mike Frysinger
Subject: [automake-commit] branch master updated: m4: speed up filesystem modification checks
Date: Mon, 14 Feb 2022 07:15:59 -0500

This is an automated email from the git hooks/post-receive script.

vapier pushed a commit to branch master
in repository automake.

View the commit online:
https://git.savannah.gnu.org/gitweb/?p=automake.git;a=commitdiff;h=720a1153134b833de9298927a432b4ea266216fb

The following commit(s) were added to refs/heads/master by this push:
     new 720a11531 m4: speed up filesystem modification checks
720a11531 is described below

commit 720a1153134b833de9298927a432b4ea266216fb
Author: Mike Frysinger <vapier@gentoo.org>
AuthorDate: Sat Feb 12 03:41:06 2022 -0500

    m4: speed up filesystem modification checks
    
    The current code sleeps at least 1 second to make sure the generated
    files are strictly newer than the source files.  It does this for a
    few reasons: POSIX only guarantees that `sleep` accept integers, and
    filesystems have a history (c.f. Windows) of bad timestamp resolution.
    
    For the first part, we can easily probe sleep to see if it accepts a
    decimal number with a fractional part -- just run `sleep 0.001`.
    
    For the second part, we can create two files and then run sleep in a
    loop to see when one is considered newer than the other.
    
    For many projects, this 1 second delay is largely amortized by the
    rest of the configure script.  Autoconf lends itself to being both
    large & slow.  But in projects with many smallish configure scripts
    with many cached vars, the time to rerun is dominated by this single
    sleep call.  For example, building libgloss against a compiler with
    many (60+) multilib configurations, we see:
    [Using sleep 1]
    $ time ./config.status
    real    2m28.164s
    user    0m33.651s
    sys     0m9.083s
    [Using sleep 0.1]
    $ time ./config.status
    real    0m39.569s
    user    0m33.517s
    sys     0m8.969s
    
    And in case anyone wonders, going below 0.1s doesn't seem to make a
    statistically significant difference, at least in this configuration.
    It appears to be within "noise" limits.
    [Using sleep 0.001]
    $ time ./config.status
    real    0m39.760s
    user    0m33.342s
    sys     0m9.080s
    
    * NEWS: Mention updated timestamp checking.
    * m4/sanity.m4: Determine whether `sleep` accepts fractional seconds.
    Determine (roughly) the filesystem timestamp resolution.  Use this to
    sleep less when waiting for generated file timestamps to update.
---
 NEWS         |  3 +++
 m4/sanity.m4 | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 40384264c..74ad6d612 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,9 @@ New in 1.17:
 
   - AM_TEXI2FLAGS may be defined to pass extra flags to TEXI2DVI & TEXI2PDF.
 
+  - Generated file timestamp checks now handle filesystems with sub-second
+    timestamp granularity dynamically.
+
 * Obsolescent features:
 
   - py-compile no longer supports Python 0.x or 1.x versions.  Python 2.0,
diff --git a/m4/sanity.m4 b/m4/sanity.m4
index 4e44dd9c4..5aa1e3ad8 100644
--- a/m4/sanity.m4
+++ b/m4/sanity.m4
@@ -6,10 +6,52 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
+# _AM_SLEEP_FRACTIONAL_SECONDS
+# ----------------------------
+AC_DEFUN([_AM_SLEEP_FRACTIONAL_SECONDS], [dnl
+AC_CACHE_CHECK([whether sleep supports fractional seconds], 
am_cv_sleep_fractional_seconds, [dnl
+AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=true], 
[am_cv_sleep_fractional_seconds=false])
+])])
+
+# _AM_FILESYSTEM_TIMESTAMP_RESOLUTION
+# -----------------------------------
+# Determine the filesystem timestamp resolution.  Modern systems are nanosecond
+# capable, but historical systems could be millisecond, second, or even 
2-second
+# resolution.
+AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl
+AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS])
+AC_CACHE_CHECK([the filesystem timestamp resolution], 
am_cv_filesystem_timestamp_resolution, [dnl
+# Use names that lexically sort older-first when the timestamps are equal.
+rm -f conftest.file.a conftest.file.b
+: > conftest.file.a
+AS_IF([$am_cv_sleep_fractional_seconds], [dnl
+  am_try_sleep=0.1 am_try_loops=20
+], [dnl
+  am_try_sleep=1   am_try_loops=2
+])
+am_try=0
+while :; do
+  AS_VAR_ARITH([am_try], [$am_try + 1])
+  echo "timestamp $am_try" > conftest.file.b
+  set X `ls -t conftest.file.a conftest.file.b`
+  if test "$[2]" = conftest.file.b || test $am_try -eq $am_try_loops; then
+    break
+  fi
+  sleep $am_try_sleep
+done
+rm -f conftest.file.a conftest.file.b
+am_cv_filesystem_timestamp_resolution=$am_try
+AS_IF([$am_cv_sleep_fractional_seconds], [dnl
+  AS_VAR_ARITH([am_cv_filesystem_timestamp_resolution], [$am_try / 10])
+  AS_VAR_ARITH([am_fraction], [$am_try % 10])
+  AS_VAR_APPEND([am_cv_filesystem_timestamp_resolution], [.$am_fraction])
+])
+])])
+
 # AM_SANITY_CHECK
 # ---------------
 AC_DEFUN([AM_SANITY_CHECK],
-[dnl
+[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION])
 rm -f conftest.file
 AC_CACHE_CHECK([whether build environment is sane], am_cv_build_env_is_sane, 
[dnl
 # Reject unsafe characters in $srcdir or the absolute working directory
@@ -53,7 +95,7 @@ if (
        break
      fi
      # Just in case.
-     sleep 1
+     sleep $am_cv_filesystem_timestamp_resolution
      am_has_slept=yes
    done
    test "$[2]" = conftest.file
@@ -69,7 +111,7 @@ fi
 # generated files are strictly newer.
 am_sleep_pid=
 if ! test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1; 
then
-  ( sleep 1 ) &
+  ( sleep $am_cv_filesystem_timestamp_resolution ) &
   am_sleep_pid=$!
 fi
 AC_CONFIG_COMMANDS_PRE(



reply via email to

[Prev in Thread] Current Thread [Next in Thread]