summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/thread/qthread.cpp17
-rw-r--r--src/corelib/thread/qthread_unix.cpp33
2 files changed, 43 insertions, 7 deletions
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index a936d189f4c..4cfcab2258d 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -314,9 +314,20 @@ QThreadPrivate::~QThreadPrivate()
/*!
\fn int QThread::idealThreadCount()
- Returns the ideal number of threads that can be run on the system. This is done querying
- the number of processor cores, both real and logical, in the system. This function returns 1
- if the number of processor cores could not be detected.
+ Returns the ideal number of threads that this process can run in parallel.
+ This is done by querying the number of logical processors available to this
+ process (if supported by this OS) or the total number of logical processors
+ in the system. This function returns 1 if neither value could be
+ determined.
+
+ \note On operating systems that support setting a thread's affinity to a
+ subset of all logical processors, the value returned by this function may
+ change between threads and over time.
+
+ \note On operating systems that support CPU hotplugging and hot-unplugging,
+ the value returned by this function may also change over time (and note
+ that CPUs can be turned on and off by software, without a physical,
+ hardware change).
*/
/*!
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 8fa4e939f83..79abfe7e500 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -70,8 +70,10 @@
#include <sched.h>
#include <errno.h>
-#ifdef Q_OS_BSD4
-#include <sys/sysctl.h>
+#if defined(Q_OS_FREEBSD)
+# include <sys/cpuset.h>
+#elif defined(Q_OS_BSD4)
+# include <sys/sysctl.h>
#endif
#ifdef Q_OS_VXWORKS
# if (_WRS_VXWORKS_MAJOR > 6) || ((_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR >= 6))
@@ -455,8 +457,31 @@ int QThread::idealThreadCount() noexcept
} else {
cores = (int)psd.psd_proc_cnt;
}
+#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
+# ifdef Q_OS_FREEBSD
+# define CPU_COUNT_S(setsize, cpusetp) ((int)BIT_COUNT(setsize, cpusetp))
+ // match the Linux API for simplicity
+ using cpu_set_t = cpuset_t;
+ auto sched_getaffinity = [](pid_t, size_t cpusetsize, cpu_set_t *mask) {
+ return cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, cpusetsize, mask);
+ };
+# endif
+
+ // get the number of threads we're assigned, not the total in the system
+ QVarLengthArray<cpu_set_t, 1> cpuset(1);
+ int size = 1;
+ if (Q_UNLIKELY(sched_getaffinity(0, sizeof(cpu_set_t), cpuset.data()) < 0)) {
+ for (size = 2; size <= 4; size *= 2) {
+ cpuset.resize(size);
+ if (sched_getaffinity(0, sizeof(cpu_set_t) * size, cpuset.data()) == 0)
+ break;
+ }
+ if (size > 4)
+ return 1;
+ }
+ cores = CPU_COUNT_S(sizeof(cpu_set_t) * size, cpuset.data());
#elif defined(Q_OS_BSD4)
- // FreeBSD, OpenBSD, NetBSD, BSD/OS, OS X, iOS
+ // OpenBSD, NetBSD, BSD/OS, Darwin (macOS, iOS, etc.)
size_t len = sizeof(cores);
int mib[2];
mib[0] = CTL_HW;
@@ -494,7 +519,7 @@ int QThread::idealThreadCount() noexcept
#elif defined(Q_OS_WASM)
cores = QThreadPrivate::idealThreadCount;
#else
- // the rest: Linux, Solaris, AIX, Tru64
+ // the rest: Solaris, AIX, Tru64
cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
if (cores == -1)
return 1;