Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -269,6 +269,7 @@ add_definitions( -D_GNU_SOURCE ) endif() # This check requires _GNU_SOURCE +check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY) if(HAVE_LIBPTHREAD) check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP) check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP) Index: include/llvm/Config/config.h.cmake =================================================================== --- include/llvm/Config/config.h.cmake +++ include/llvm/Config/config.h.cmake @@ -185,6 +185,9 @@ /* Define to 1 if you have the `setenv' function. */ #cmakedefine HAVE_SETENV ${HAVE_SETENV} +/* Define to 1 if you have the `sched_getaffinity' function. */ +#cmakedefine HAVE_SCHED_GETAFFINITY ${HAVE_SCHED_GETAFFINITY} + /* Define to 1 if you have the `setrlimit' function. */ #cmakedefine HAVE_SETRLIMIT ${HAVE_SETRLIMIT} Index: include/llvm/Support/ThreadPool.h =================================================================== --- include/llvm/Support/ThreadPool.h +++ include/llvm/Support/ThreadPool.h @@ -38,8 +38,8 @@ using TaskTy = std::function; using PackagedTaskTy = std::packaged_task; - /// Construct a pool with the number of core available on the system (or - /// whatever the value returned by std::thread::hardware_concurrency() is). + /// Construct a pool with the number of threads found by + /// get_available_threads(). ThreadPool(); /// Construct a pool of \p ThreadCount threads Index: include/llvm/Support/Threading.h =================================================================== --- include/llvm/Support/Threading.h +++ include/llvm/Support/Threading.h @@ -131,6 +131,14 @@ /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF unsigned heavyweight_hardware_concurrency(); + /// Get the number of threads that the current program can execute + /// concurrently. On some systems std::thread::hardware_concurrency() returns + /// the total number of cores, without taking affinity into consideration. + /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF. + /// Fallback to std::thread::hardware_concurrency() if sched_getaffinity is + /// not available. + unsigned hardware_concurrency(); + /// \brief Return the current thread id, as used in various OS system calls. /// Note that not all platforms guarantee that the value returned will be /// unique across the entire system, so portable code should not assume Index: lib/Fuzzer/FuzzerUtil.cpp =================================================================== --- lib/Fuzzer/FuzzerUtil.cpp +++ lib/Fuzzer/FuzzerUtil.cpp @@ -196,9 +196,9 @@ } unsigned NumberOfCpuCores() { - unsigned N = std::thread::hardware_concurrency(); + unsigned N = get_available_threads(); if (!N) { - Printf("WARNING: std::thread::hardware_concurrency not well defined for " + Printf("WARNING: get_available_threads not well defined for " "your platform. Assuming CPU count of 1.\n"); N = 1; } Index: lib/Support/Parallel.cpp =================================================================== --- lib/Support/Parallel.cpp +++ lib/Support/Parallel.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/Parallel.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Threading.h" #include #include @@ -70,8 +71,7 @@ /// in filo order. class ThreadPoolExecutor : public Executor { public: - explicit ThreadPoolExecutor( - unsigned ThreadCount = std::thread::hardware_concurrency()) + explicit ThreadPoolExecutor(unsigned ThreadCount = hardware_concurrency()) : Done(ThreadCount) { // Spawn all but one of the threads in another thread as spawning threads // can take a while. Index: lib/Support/ThreadPool.cpp =================================================================== --- lib/Support/ThreadPool.cpp +++ lib/Support/ThreadPool.cpp @@ -14,14 +14,15 @@ #include "llvm/Support/ThreadPool.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; #if LLVM_ENABLE_THREADS -// Default to std::thread::hardware_concurrency -ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {} +// Default to hardware_concurrency +ThreadPool::ThreadPool() : ThreadPool(hardware_concurrency()) {} ThreadPool::ThreadPool(unsigned ThreadCount) : ActiveThreads(0), EnableFlag(true) { Index: lib/Support/Threading.cpp =================================================================== --- lib/Support/Threading.cpp +++ lib/Support/Threading.cpp @@ -47,6 +47,8 @@ unsigned llvm::heavyweight_hardware_concurrency() { return 1; } +unsigned llvm::get_available_threads() { return 1; } + uint64_t llvm::get_threadid() { return 0; } uint32_t llvm::get_max_thread_name_length() { return 0; } @@ -71,6 +73,15 @@ return NumPhysical; } +unsigned llvm::hardware_concurrency() { +#ifdef HAVE_SCHED_GETAFFINITY + cpu_set_t Set; + if (sched_getaffinity(0, sizeof(Set), &Set)) + return CPU_COUNT(&Set); +#endif + return std::thread::hardware_concurrency(); +} + // Include the platform-specific parts of this class. #ifdef LLVM_ON_UNIX #include "Unix/Threading.inc" Index: tools/llvm-profdata/llvm-profdata.cpp =================================================================== --- tools/llvm-profdata/llvm-profdata.cpp +++ tools/llvm-profdata/llvm-profdata.cpp @@ -211,8 +211,8 @@ // If NumThreads is not specified, auto-detect a good default. if (NumThreads == 0) - NumThreads = std::max(1U, std::min(std::thread::hardware_concurrency(), - unsigned(Inputs.size() / 2))); + NumThreads = std::max( + 1U, std::min(hardware_concurrency(), unsigned(Inputs.size() / 2))); // Initialize the writer contexts. SmallVector, 4> Contexts;