Collin Funk <[email protected]> writes:

> I can have a look at them. I assume there is a sysctl somewhere, but
> I'll come back to the list if I get stuck.

I have attached a patch that works on FreeBSD. Here is it compared to
the values reported by 'top' on cfarm240:

    $ top | grep '^Mem:'
    Mem: 18M Active, 238M Inact, 11G Wired, 104K Buf, 50G Free
    $ ./gltests/test-physmem
    Total memory:      68642877440 B =  65463 MiB
    Available memory:  54081216512 B =  51576 MiB

Collin

>From 85715a7888eb68abb80233734c45ea2334762e2d Mon Sep 17 00:00:00 2001
Message-ID: <85715a7888eb68abb80233734c45ea2334762e2d.1784086910.git.collin.fu...@gmail.com>
From: Collin Funk <[email protected]>
Date: Tue, 14 Jul 2026 20:31:54 -0700
Subject: [PATCH] physmem: allow physmem_claimable to return more than 8 GiB on
 FreeBSD.

Problem reported by Bruno Haible in:
<https://lists.gnu.org/r/bug-gnulib/2026-07/msg00046.html>.

* m4/physmem.m4 (gl_PHYSMEM): Check for the sysctlbyname function.
* lib/physmem.c (physmem_claimable) [HAVE_SYSCTLBYNAME && __FreeBSD__]:
Calculate of free memory from some FreeBSD-specific sysctl strings.
---
 ChangeLog     |  9 +++++++++
 lib/physmem.c | 21 +++++++++++++++++++++
 m4/physmem.m4 |  4 ++--
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 81ba3ad21c..21e3b969c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2026-07-14  Collin Funk  <[email protected]>
+
+	physmem: allow physmem_claimable to return more than 8 GiB on FreeBSD.
+	Problem reported by Bruno Haible in:
+	<https://lists.gnu.org/r/bug-gnulib/2026-07/msg00046.html>.
+	* m4/physmem.m4 (gl_PHYSMEM): Check for the sysctlbyname function.
+	* lib/physmem.c (physmem_claimable) [HAVE_SYSCTLBYNAME && __FreeBSD__]:
+	Calculate of free memory from some FreeBSD-specific sysctl strings.
+
 2026-07-14  Bruno Haible  <[email protected]>
 
 	vasnwprintf-extra-tests: Refactor.
diff --git a/lib/physmem.c b/lib/physmem.c
index 90e4fe2424..5b37ca232c 100644
--- a/lib/physmem.c
+++ b/lib/physmem.c
@@ -277,6 +277,27 @@ physmem_claimable (double aggressivity)
   }
 #endif
 
+#if HAVE_SYSCTLBYNAME && defined __FreeBSD__
+  { /* This works on FreeBSD.  */
+    unsigned int free_pages;
+    unsigned int inactive_pages;
+    size_t len = sizeof free_pages;
+
+    if (sysctlbyname ("vm.stats.vm.v_free_count", &free_pages,
+                      &len, NULL, 0) == 0 && len == sizeof free_pages
+        && (len = sizeof inactive_pages,
+            sysctlbyname ("vm.stats.vm.v_inactive_count", &inactive_pages,
+                          &len, NULL, 0) == 0)
+        && len == sizeof inactive_pages)
+      {
+        /* Avoid integer overflow when multiplying the number of pages by the
+           page size.  */
+        unsigned long long int page_size = getpagesize ();
+        return (free_pages + inactive_pages) * page_size;
+      }
+  }
+#endif
+
 #if HAVE_SYSCTL && !(defined __GLIBC__ && defined __linux__) && defined HW_USERMEM
   { /* This works on *bsd, kfreebsd-gnu, and darwin.  */
     unsigned int usermem;
diff --git a/m4/physmem.m4 b/m4/physmem.m4
index ae5c01a671..824ab451c5 100644
--- a/m4/physmem.m4
+++ b/m4/physmem.m4
@@ -1,5 +1,5 @@
 # physmem.m4
-# serial 13
+# serial 14
 dnl Copyright (C) 2002-2003, 2005-2006, 2008-2026 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -42,7 +42,7 @@ AC_DEFUN([gl_PHYSMEM]
      #endif
     ])
 
-  AC_CHECK_FUNCS([pstat_getstatic pstat_getdynamic getsysinfo sysctl table sysinfo])
+  AC_CHECK_FUNCS([pstat_getstatic pstat_getdynamic getsysinfo sysctl sysctlbyname table sysinfo])
   AC_CHECK_MEMBERS([struct sysinfo.mem_unit],,, [[#include <sys/sysinfo.h>]])
   AC_REQUIRE([gl_SYS__SYSTEM_CONFIGURATION])
 ])
-- 
2.55.0

Reply via email to