From fe82637069bfdf09c9fcb45076379fd79291d09a Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 4 Jan 2019 11:57:12 -0800 Subject: [PATCH] Fix #1425 - Use physical core count API on FreeBSD 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 | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/programs/util.c b/programs/util.c index 34634318..49eea148 100644 --- a/programs/util.c +++ b/programs/util.c @@ -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 +#include + +/* 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;