From d3b5705c94fa5d2a55b20ac61378eab17b00dc99 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 17 Jan 2025 09:25:09 -0800 Subject: [PATCH] QThread/Linux & FreeBSD: replace the QVLA with a real VLA and bump max We don't need to use the heap, because this array won't get too big. This commit raises the limit from 4096 logical processors on Linux to 1048576 (i.e., the square). 4096 is less than one system I've had access to since I wrote this code in 2021 (64 sockets of hyperthreaded 60-core Intel 4th Generation Xeon Scalable processors = 7680 logical processors). The 4096 limit would also be reached by a "mere" 16 sockets of 288-core Intel Xeon 6E processors. I've also made it grow slightly faster by multiplying by 4 instead of 2. Change-Id: I7c0d8b5e7809faba72c2fffdf99500868dfd7db4 Reviewed-by: Marc Mutz Reviewed-by: Ahmad Samir --- src/corelib/thread/qthread_unix.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 3de6acf3831..f8bf4ba63c9 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -502,19 +502,24 @@ int QThread::idealThreadCount() noexcept cores = (int)psd.psd_proc_cnt; } #elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD) + QT_WARNING_PUSH +# if defined(Q_CC_CLANG) && Q_CC_CLANG >= 1800 + QT_WARNING_DISABLE_CLANG("-Wvla-cxx-extension") +# endif + // get the number of threads we're assigned, not the total in the system - QVarLengthArray 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; + constexpr qsizetype MaxCpuCount = 1024 * 1024; + constexpr qsizetype MaxCpuSetArraySize = MaxCpuCount / sizeof(cpu_set_t) / 8; + qsizetype size = 1; + do { + cpu_set_t cpuset[size]; + if (sched_getaffinity(0, sizeof(cpu_set_t) * size, cpuset) == 0) { + cores = CPU_COUNT_S(sizeof(cpu_set_t) * size, cpuset); + break; } - if (size > 4) - return 1; - } - cores = CPU_COUNT_S(sizeof(cpu_set_t) * size, cpuset.data()); + size *= 4; + } while (size < MaxCpuSetArraySize); + QT_WARNING_POP #elif defined(Q_OS_BSD4) // OpenBSD, NetBSD, BSD/OS, Darwin (macOS, iOS, etc.) size_t len = sizeof(cores);