MCPcopy Create free account
hub / github.com/bshoshany/thread-pool / get_os_thread_affinity

Method get_os_thread_affinity

include/BS_thread_pool.hpp:998–1040  ·  view source on GitHub ↗

* @brief Get the processor affinity of the current thread using the current platform's native API. This should work on Windows and Linux, but is not possible on macOS and Android as the native API does not allow it. * * @return An `std::optional` object, optionally containing the processor affinity of the current thread as an `std::vector ` where each element corresponds to a logica

Source from the content-addressed store, hash-verified

996 * @return An `std::optional` object, optionally containing the processor affinity of the current thread as an `std::vector<bool>` where each element corresponds to a logical processor. If the returned object does not contain a value, then the affinity could not be determined. On macOS and Android, this function always returns `std::nullopt`.
997 */
998 [[nodiscard]] static std::optional<std::vector<bool>> get_os_thread_affinity()
999 {
1000 #if defined(_WIN32)
1001 // Windows does not have a `GetThreadAffinityMask()` function, but `SetThreadAffinityMask()` returns the previous affinity mask, so we can use that to get the current affinity and then restore it. It's a bit of a hack, but it works. Since the thread affinity must be a subset of the process affinity, we use the process affinity as the temporary value.
1002 DWORD_PTR process_mask = 0;
1003 DWORD_PTR system_mask = 0;
1004 if (GetProcessAffinityMask(GetCurrentProcess(), &process_mask, &system_mask) == 0)
1005 return std::nullopt;
1006 const DWORD_PTR previous_mask = SetThreadAffinityMask(GetCurrentThread(), process_mask);
1007 if (previous_mask == 0)
1008 return std::nullopt;
1009 SetThreadAffinityMask(GetCurrentThread(), previous_mask);
1010 #ifdef __cpp_lib_int_pow2
1011 const std::size_t num_cpus = static_cast<std::size_t>(std::bit_width(system_mask));
1012 #else
1013 std::size_t num_cpus = 0;
1014 if (system_mask != 0)
1015 {
1016 num_cpus = 1;
1017 while ((system_mask >>= 1U) != 0U)
1018 ++num_cpus;
1019 }
1020 #endif
1021 std::vector<bool> affinity(num_cpus);
1022 for (std::size_t i = 0; i < num_cpus; ++i)
1023 affinity[i] = ((previous_mask & (1ULL << i)) != 0ULL);
1024 return affinity;
1025 #elif defined(__linux__) && !defined(__ANDROID__)
1026 cpu_set_t cpu_set;
1027 CPU_ZERO(&cpu_set);
1028 if (pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set) != 0)
1029 return std::nullopt;
1030 const int num_cpus = get_nprocs();
1031 if (num_cpus < 1)
1032 return std::nullopt;
1033 std::vector<bool> affinity(static_cast<std::size_t>(num_cpus));
1034 for (std::size_t i = 0; i < affinity.size(); ++i)
1035 affinity[i] = CPU_ISSET(i, &cpu_set);
1036 return affinity;
1037 #else
1038 return std::nullopt;
1039 #endif
1040 }
1041
1042 /**
1043 * @brief Set the processor affinity of the current thread using the current platform's native API. This should work on Windows and Linux, but is not possible on macOS and Android as the native API does not allow it. Note that the thread affinity must be a subset of the process affinity (as obtained using `BS::get_os_process_affinity()`) for the containing process of a thread.

Callers

nothing calls this directly

Calls 1

sizeMethod · 0.80

Tested by

no test coverage detected