summaryrefslogtreecommitdiffstats
path: root/Source/cmAffinity.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmAffinity.cxx')
-rw-r--r--Source/cmAffinity.cxx62
1 files changed, 62 insertions, 0 deletions
diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx
new file mode 100644
index 0000000..bdf1f42
--- /dev/null
+++ b/Source/cmAffinity.cxx
@@ -0,0 +1,62 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmAffinity.h"
+
+#include "cm_uv.h"
+
+#ifndef CMAKE_USE_SYSTEM_LIBUV
+#ifdef _WIN32
+#define CM_HAVE_CPU_AFFINITY
+#include <windows.h>
+#elif defined(__linux__) || defined(__FreeBSD__)
+#define CM_HAVE_CPU_AFFINITY
+#include <pthread.h>
+#include <sched.h>
+#if defined(__FreeBSD__)
+#include <pthread_np.h>
+#include <sys/cpuset.h>
+#include <sys/param.h>
+#endif
+#if defined(__linux__)
+typedef cpu_set_t cm_cpuset_t;
+#else
+typedef cpuset_t cm_cpuset_t;
+#endif
+#endif
+#endif
+
+namespace cmAffinity {
+
+std::set<size_t> GetProcessorsAvailable()
+{
+ std::set<size_t> processorsAvailable;
+#ifdef CM_HAVE_CPU_AFFINITY
+ int cpumask_size = uv_cpumask_size();
+ if (cpumask_size > 0) {
+#ifdef _WIN32
+ DWORD_PTR procmask;
+ DWORD_PTR sysmask;
+ if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask) !=
+ 0) {
+ for (int i = 0; i < cpumask_size; ++i) {
+ if (procmask & (((DWORD_PTR)1) << i)) {
+ processorsAvailable.insert(i);
+ }
+ }
+ }
+#else
+ cm_cpuset_t cpuset;
+ CPU_ZERO(&cpuset); // NOLINT(clang-tidy)
+ if (pthread_getaffinity_np(pthread_self(), sizeof(cpuset), &cpuset) == 0) {
+ for (int i = 0; i < cpumask_size; ++i) {
+ if (CPU_ISSET(i, &cpuset)) {
+ processorsAvailable.insert(i);
+ }
+ }
+ }
+#endif
+ }
+#endif
+ return processorsAvailable;
+}
+}