cmAffinity.cxx 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. #include "cm_uv.h"
  5. #ifndef CMAKE_USE_SYSTEM_LIBUV
  6. # ifdef _WIN32
  7. # define CM_HAVE_CPU_AFFINITY
  8. # include <windows.h>
  9. # elif defined(__linux__) || defined(__FreeBSD__)
  10. # define CM_HAVE_CPU_AFFINITY
  11. # include <pthread.h>
  12. # include <sched.h>
  13. // On some platforms CPU_ZERO needs memset but sched.h forgets string.h
  14. # include <string.h> // IWYU pragma: keep
  15. # if defined(__FreeBSD__)
  16. # include <pthread_np.h>
  17. # include <sys/cpuset.h>
  18. # include <sys/param.h>
  19. # endif
  20. # if defined(__linux__)
  21. using cm_cpuset_t = cpu_set_t;
  22. # else
  23. using cm_cpuset_t = cpuset_t;
  24. # endif
  25. # endif
  26. #endif
  27. namespace cmAffinity {
  28. std::set<size_t> GetProcessorsAvailable()
  29. {
  30. std::set<size_t> processorsAvailable;
  31. #ifdef CM_HAVE_CPU_AFFINITY
  32. int cpumask_size = uv_cpumask_size();
  33. if (cpumask_size > 0) {
  34. # ifdef _WIN32
  35. DWORD_PTR procmask;
  36. DWORD_PTR sysmask;
  37. if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask) !=
  38. 0) {
  39. for (int i = 0; i < cpumask_size; ++i) {
  40. if (procmask & (((DWORD_PTR)1) << i)) {
  41. processorsAvailable.insert(i);
  42. }
  43. }
  44. }
  45. # else
  46. cm_cpuset_t cpuset;
  47. CPU_ZERO(&cpuset); // NOLINT(clang-tidy)
  48. if (pthread_getaffinity_np(pthread_self(), sizeof(cpuset), &cpuset) == 0) {
  49. for (int i = 0; i < cpumask_size; ++i) {
  50. if (CPU_ISSET(i, &cpuset)) {
  51. processorsAvailable.insert(i);
  52. }
  53. }
  54. }
  55. # endif
  56. }
  57. #endif
  58. return processorsAvailable;
  59. }
  60. }