1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 file Copyright.txt or https://cmake.org/licensing for details. */ 3 #include "cmAffinity.h" 4 5 #include <cm3p/uv.h> 6 7 #ifndef CMAKE_USE_SYSTEM_LIBUV 8 # ifdef _WIN32 9 # define CM_HAVE_CPU_AFFINITY 10 # include <windows.h> 11 # elif defined(__linux__) || defined(__FreeBSD__) 12 # define CM_HAVE_CPU_AFFINITY 13 # include <pthread.h> 14 # include <sched.h> 15 // On some platforms CPU_ZERO needs memset but sched.h forgets string.h 16 # include <cstring> // IWYU pragma: keep 17 # if defined(__FreeBSD__) 18 # include <pthread_np.h> 19 20 # include <sys/cpuset.h> 21 # include <sys/param.h> 22 # endif 23 # if defined(__linux__) 24 using cm_cpuset_t = cpu_set_t; 25 # else 26 using cm_cpuset_t = cpuset_t; 27 # endif 28 # endif 29 #endif 30 31 namespace cmAffinity { 32 GetProcessorsAvailable()33std::set<size_t> GetProcessorsAvailable() 34 { 35 std::set<size_t> processorsAvailable; 36 #ifdef CM_HAVE_CPU_AFFINITY 37 int cpumask_size = uv_cpumask_size(); 38 if (cpumask_size > 0) { 39 # ifdef _WIN32 40 DWORD_PTR procmask; 41 DWORD_PTR sysmask; 42 if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask) != 43 0) { 44 for (int i = 0; i < cpumask_size; ++i) { 45 if (procmask & (((DWORD_PTR)1) << i)) { 46 processorsAvailable.insert(i); 47 } 48 } 49 } 50 # else 51 cm_cpuset_t cpuset; 52 CPU_ZERO(&cpuset); // NOLINT(clang-tidy) 53 if (pthread_getaffinity_np(pthread_self(), sizeof(cpuset), &cpuset) == 0) { 54 for (int i = 0; i < cpumask_size; ++i) { 55 if (CPU_ISSET(i, &cpuset)) { 56 processorsAvailable.insert(i); 57 } 58 } 59 } 60 # endif 61 } 62 #endif 63 return processorsAvailable; 64 } 65 } 66