]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/math-util: drop libm where possible
authorDaan De Meyer <daan@amutable.com>
Fri, 15 May 2026 14:59:49 +0000 (14:59 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 20 May 2026 14:32:22 +0000 (16:32 +0200)
- test-random-util is reworked to not use sqrt()
- pretty-print.c inlines ceil() so libm doesn't have
  to be linked into libshared
- We add fno-math-errno to allow inlining of more math
  functions by not requiring standard math functions to
  set errno on invalid input.

meson.build
src/basic/meson.build
src/libsystemd/meson.build
src/pcrlock/meson.build
src/resolve/meson.build
src/shared/pretty-print.c
src/test/meson.build
src/test/test-random-util.c

index 98dfb6784049dfde28715e67cfc72b5c71a78968..9529ea7b0648a75dbcf4e69908c33168361c5fb8 100644 (file)
@@ -425,6 +425,11 @@ possible_common_cc_flags = [
         '-fstack-protector',
         '-fstack-protector-strong',
         '-fstrict-flex-arrays=3',
+        # We don't read errno from any libm call, and the math-errno fallback
+        # forces a DT_NEEDED on libm via the cold error path even when the hot
+        # path is a single hardware instruction (sqrtsd, etc.). Drop it so the
+        # builtins lower to pure hardware instructions.
+        '-fno-math-errno',
         '--param=ssp-buffer-size=4',
 ]
 
index 20c424b45bc51d5321d95f513b8ee85423d57a1f..7cc62c7b8bdac87a49e33539ec9b9a723e653d7c 100644 (file)
@@ -215,7 +215,6 @@ libbasic_static = static_library(
         dependencies : [libbzip2_cflags,
                         libgcrypt_cflags,
                         liblz4_cflags,
-                        libm,
                         libxz_cflags,
                         libz_cflags,
                         libzstd_cflags,
index b7e11c9bb22b01f0611c5514925ac32b1fe4b377..c6cf0fad34b60ebfc7cea8269718b63b7648e8ba 100644 (file)
@@ -220,7 +220,6 @@ libsystemd_tests += [
                         libgio_cflags,
                         libglib_cflags,
                         libgobject_cflags,
-                        libm,
                 ],
         },
         {
index a80cd31947977bc4d7da8caf776a554646af2715..dbe816402deca0a5b57569c42e9a9c816fc3a435 100644 (file)
@@ -12,7 +12,6 @@ executables += [
                         'pcrlock-firmware.c',
                 ),
                 'dependencies' : [
-                        libm,
                         libopenssl_cflags,
                         tpm2,
                 ],
index 365031335557648c4630cfe908e77e9aa30f217c..f024b02047c7b2791ffaf290285487ccc94d88bd 100644 (file)
@@ -71,7 +71,6 @@ resolve_common_template = {
         'dependencies' : [
                 libidn2_cflags,
                 libopenssl_cflags,
-                libm,
         ],
 }
 
index 7a4bc10eebf2a20a87640f55a98f5f600bea47af..3328293c5d256d34c855a16c1bf008e88b59395d 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <math.h>
 #include <stdio.h>
 #include <sys/utsname.h>
 #include <unistd.h>
@@ -567,7 +566,10 @@ void draw_progress_bar_unbuffered(const char *prefix, double percentage) {
                  * https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
                  * https://github.com/microsoft/terminal/pull/8055
                  */
-                fprintf(stderr, ANSI_OSC "9;4;1;%u" ANSI_ST, (unsigned) ceil(percentage));
+                unsigned percentage_ceil = (unsigned) percentage;
+                if ((double) percentage_ceil < percentage)
+                        percentage_ceil++;
+                fprintf(stderr, ANSI_OSC "9;4;1;%u" ANSI_ST, percentage_ceil);
 
                 size_t cols = columns();
                 size_t prefix_width = utf8_console_width(prefix) + 1 /* space */;
index b581de293b30717abcc4e77f2bae5e1c01e6c607..0c8dba64d5678992795d5ccd5fecc9c36fe616ee 100644 (file)
@@ -407,7 +407,6 @@ executables += [
         },
         test_template + {
                 'sources' : files('test-parse-util.c'),
-                'dependencies' : libm,
         },
         test_template + {
                 'sources' : files('test-shift-uid.c'),
@@ -432,7 +431,6 @@ executables += [
         },
         test_template + {
                 'sources' : files('test-random-util.c'),
-                'dependencies' : libm,
                 'timeout' : 120,
         },
         test_template + {
index d5043779b702af0258de17068a1345d5b8d95d3e..bceb7b937e0a8bd4428c4fbade3a72b5575503ea 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <math.h>
-
 #include "hexdecoct.h"
 #include "log.h"
 #include "memory-util.h"
@@ -15,7 +13,7 @@ TEST(random_bytes) {
         for (size_t i = 1; i < sizeof buf; i++) {
                 random_bytes(buf, i);
                 if (i + 1 < sizeof buf)
-                        assert_se(buf[i] == 0);
+                        ASSERT_EQ(buf[i], 0);
 
                 hexdump(stdout, buf, i);
         }
@@ -25,9 +23,9 @@ TEST(crypto_random_bytes) {
         uint8_t buf[16] = {};
 
         for (size_t i = 1; i < sizeof buf; i++) {
-                assert_se(crypto_random_bytes(buf, i) == 0);
+                ASSERT_OK(crypto_random_bytes(buf, i));
                 if (i + 1 < sizeof buf)
-                        assert_se(buf[i] == 0);
+                        ASSERT_EQ(buf[i], 0);
 
                 hexdump(stdout, buf, i);
         }
@@ -53,21 +51,25 @@ static void test_random_u64_range_one(unsigned mod) {
         /* Print histogram: vertical axis — value, horizontal axis — count.
          *
          * The expected value is always TOTAL/mod, because the distribution should be flat. The expected
-         * variance is TOTAL×p×(1-p), where p==1/mod, and standard deviation the root of the variance.
-         * Assert that the deviation from the expected value is less than 6 standard deviations.
+         * variance is TOTAL×p×(1-p), where p==1/mod. Assert that the deviation from the expected value
+         * is less than 6 standard deviations by comparing squared values (diff² < 36·variance), which
+         * avoids a sqrt() call and the libm dependency that comes with it at -O0.
          */
         unsigned scale = 2 * max / (columns() < 20 ? 80 : columns() - 20);
         double exp = (double) TOTAL / mod;
+        double variance = exp * (mod > 1 ? mod - 1 : 1) / mod;
 
         for (size_t i = 0; i < mod; i++) {
-                double dev = (count[i] - exp) / sqrt(exp * (mod > 1 ? mod - 1 : 1) / mod);
-                log_debug("%02zu: %5u (%+.3f)%*s",
-                          i, count[i], dev,
+                double diff = count[i] - exp;
+                double dev_sq = diff * diff / variance;
+
+                log_debug("%02zu: %5u (z²=%.3f)%*s",
+                          i, count[i], dev_sq,
                           (int) (count[i] / scale), "x");
 
-                assert_se(ABS(dev) < 6); /* 6 sigma is excessive, but this check should be enough to
-                                           * identify catastrophic failure while minimizing false
-                                           * positives. */
+                ASSERT_TRUE(dev_sq < 36); /* 36 = 6²; 6 sigma is excessive, but this check should be
+                                           * enough to identify catastrophic failure while minimizing
+                                           * false positives. */
         }
 }