]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fix #1425 - Use physical core count API on FreeBSD 1491/head
authorConrad Meyer <cem@FreeBSD.org>
Fri, 4 Jan 2019 19:57:12 +0000 (11:57 -0800)
committerConrad Meyer <cem@FreeBSD.org>
Fri, 4 Jan 2019 19:57:12 +0000 (11:57 -0800)
Similar to Apple, use the native physical core count sysctl, when available.

This is a little repetitive (it's basically the __APPLE__ method plus the
otherBSD method concatenated together) but seemed clearer than any way that
would totally eliminate repetition.

The __FreeBSD_version check only tests the version of the FreeBSD kernel
that zstd is compiled on; importantly, it may be run on a different version.
So the compile-time check is a little naive and needs to be able to fallback
to work on older versions of FreeBSD.  For a similar reason, it may make
sense to simply eliminate the __FreeBSD_version check entirely.  The
tradeoff is that a spurious sysctlbyname would be issued when -T0 is used on
older kernels.

programs/util.c

index 34634318c638ac71f040627245cf68efc8e9581c..49eea148ec1834748aa243bf1f368e299753860d 100644 (file)
@@ -640,10 +640,42 @@ failed:
     }
 }
 
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#elif defined(__FreeBSD__)
 
-/* Use apple-provided syscall
- * see: man 3 sysctl */
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+/* Use physical core sysctl when available
+ * see: man 4 smp, man 3 sysctl */
+int UTIL_countPhysicalCores(void)
+{
+    static int numPhysicalCores = 0; /* freebsd sysctl is native int sized */
+    if (numPhysicalCores != 0) return numPhysicalCores;
+
+#if __FreeBSD_version >= 1300008
+    {   size_t size = sizeof(numPhysicalCores);
+        int ret = sysctlbyname("kern.smp.cores", &numPhysicalCores, &size, NULL, 0);
+        if (ret == 0) return numPhysicalCores;
+        if (errno != ENOENT) {
+            perror("zstd: can't get number of physical cpus");
+            exit(1);
+        }
+        /* sysctl not present, fall through to older sysconf method */
+    }
+#endif
+
+    numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
+    if (numPhysicalCores == -1) {
+        /* value not queryable, fall back on 1 */
+        numPhysicalCores = 1;
+    }
+    return numPhysicalCores;
+}
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+
+/* Use POSIX sysconf
+ * see: man 3 sysconf */
 int UTIL_countPhysicalCores(void)
 {
     static int numPhysicalCores = 0;