Commit 73e844bf authored by Ben Gamari's avatar Ben Gamari 🐢 Committed by Ben Gamari
Browse files

rts: Teach getNumProcessors to return available processors

Previously we would report the number of physical processors, which
can be quite wrong in a containerized setting. Now we rather return how
many processors are in our affinity mask when possible.

I also refactored the code to prefer platform-specific since this will
report logical CPUs instead of physical (using
`machdep.cpu.thread_count` on Darwin and `cpuset_getaffinity` on FreeBSD).

Fixes #14781.

(cherry picked from commit 4413828b)
parent f3d01df7
Pipeline #45011 failed with stages
in 424 minutes and 46 seconds
......@@ -982,7 +982,7 @@ FP_CHECK_FUNC([GetModuleFileName],
dnl ** check for more functions
dnl ** The following have been verified to be used in ghc/, but might be used somewhere else, too.
AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity setlocale])
AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity sched_getaffinity setlocale])
dnl ** On OS X 10.4 (at least), time.h doesn't declare ctime_r if
dnl ** _POSIX_C_SOURCE is defined
......
......@@ -285,20 +285,42 @@ getNumberOfProcessors (void)
uint32_t nproc = RELAXED_LOAD(&nproc_cache);
if (nproc == 0) {
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
nproc = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
nproc = sysconf(_SC_NPROCESSORS_CONF);
#elif defined(darwin_HOST_OS)
#if defined(HAVE_SCHED_GETAFFINITY)
cpu_set_t mask;
CPU_ZERO(&mask);
if (sched_getaffinity(0, sizeof(mask), &mask) == 0) {
for (int i = 0; i < CPU_SETSIZE; i++) {
if (CPU_ISSET(i, &mask))
nproc++;
}
return nproc;
}
#endif
#if defined(darwin_HOST_OS)
size_t size = sizeof(uint32_t);
if(sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) {
if (sysctlbyname("machdep.cpu.thread_count",&nproc,&size,NULL,0) != 0) {
if (sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) {
if (sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0)
nproc = 1;
}
}
#elif defined(freebsd_HOST_OS)
cpuset_t mask;
CPU_ZERO(&mask);
if(cpuset_getaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(mask), &mask) == 0) {
return CPU_COUNT(&mask);
} else {
size_t size = sizeof(uint32_t);
if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0)
nproc = 1;
}
#elif defined(freebsd_HOST_OS)
size_t size = sizeof(uint32_t);
if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0)
nproc = 1;
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
// N.B. This is the number of physical processors.
nproc = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
// N.B. This is the number of physical processors.
nproc = sysconf(_SC_NPROCESSORS_CONF);
#else
nproc = 1;
#endif
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment