timeout: remove dependence on libm

This was seen to add about 100,000 ns to the startup time,
on a 2.6 GHz i7-5600U with glibc 2.40.

* .gitignore: Remove /lib/fenv.h.
* bootstrap.conf: Remove fenv-rounding and signbit deps.
* src/local.mk: Remove fenv lib dependency.
* src/timeout.c (is_negative): A new helper function to
be equivalent of signbit in the underflow case.
(parse_duration): Remove the rounding up logic,
as a nanosecond here or there has no significance.
This commit is contained in:
Pádraig Brady 2025-04-05 21:48:05 +01:00
parent 65b694257f
commit dce566553c
4 changed files with 11 additions and 31 deletions

1
.gitignore vendored
View File

@ -67,7 +67,6 @@
/lib/errno.h
/lib/error.h
/lib/fcntl.h
/lib/fenv.h
/lib/float.h
/lib/fnmatch.h
/lib/getopt-cdefs.h

View File

@ -99,7 +99,6 @@ gnulib_modules="
fdatasync
fdopen
fdutimensat
fenv-rounding
file-has-acl
file-type
fileblocks
@ -243,7 +242,6 @@ gnulib_modules="
settime
sig2str
sigaction
signbit
skipchars
smack
ssize_t

View File

@ -257,9 +257,6 @@ src_stat_LDADD += $(LIB_SELINUX)
# for nvlist_lookup_uint64_array
src_stat_LDADD += $(LIB_NVPAIR)
# for fegetround, fesetround
src_timeout_LDADD += $(FENV_ROUNDING_LIBM)
# for gettime, settime, tempname, utimecmp, utimens
copy_ldadd += $(CLOCK_TIME_LIB)
src_date_LDADD += $(CLOCK_TIME_LIB)

View File

@ -45,9 +45,8 @@
Written by Pádraig Brady. */
#include <config.h>
#include <fenv.h>
#include <ctype.h>
#include <getopt.h>
#include <math.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
@ -354,32 +353,25 @@ apply_time_suffix (double *x, char suffix_char)
return true;
}
ATTRIBUTE_PURE static bool
is_negative (char const *num)
{
while (*num && isspace (to_uchar (*num)))
num++;
return *num == '-';
}
static double
parse_duration (char const *str)
{
/* If possible tell strtod to round up, so that we always wait at
least as long as STR specifies. Although Standard C requires
FENV_ACCESS ON, don't bother if using GCC as it warns. */
#ifdef FE_UPWARD
# if !defined __GNUC__ && 199901 <= __STDC_VERSION__
# pragma STDC FENV_ACCESS ON
# endif
int round = fegetround ();
fesetround (FE_UPWARD);
#endif
char *ep;
double duration = cl_strtod (str, &ep);
#ifdef FE_UPWARD
fesetround (round);
#endif
if (ep == str
/* Nonnegative interval. */
|| ! (0 <= duration)
/* The interval did not underflow to -0. */
|| (signbit (duration) && errno == ERANGE)
|| (errno == ERANGE && is_negative (str))
/* No extra chars after the number and an optional s,m,h,d char. */
|| (*ep && *(ep + 1))
/* Check any suffix char and update timeout based on the suffix. */
@ -391,16 +383,10 @@ parse_duration (char const *str)
/* Do not let the duration underflow to 0, as 0 disables the timeout.
Use 2**-30 instead of 0; settimeout will round it up to 1 ns,
whereas 1e-9 might double-round to 2 ns.
whereas 1e-9 might double-round to 2 ns. */
If FE_UPWARD is defined, this code is not needed on glibc as its
strtod rounds upward correctly. Although this code might not be
needed on non-glibc platforms too, it's too much trouble to
worry about that. */
#if !defined FE_UPWARD || !defined __GLIBC__
if (duration == 0 && errno == ERANGE)
duration = 9.313225746154785e-10;
#endif
return duration;
}