29 #ifndef PIRANHA_THREAD_MANAGEMENT_HPP 30 #define PIRANHA_THREAD_MANAGEMENT_HPP 35 #include <piranha/config.hpp> 37 #include <piranha/runtime_info.hpp> 38 #include <piranha/safe_cast.hpp> 39 #include <piranha/thread_management.hpp> 41 #if defined(PIRANHA_HAVE_PTHREAD_AFFINITY) 57 inline int posix_cpu_count(::cpu_set_t *
set)
59 #if defined(CPU_COUNT) 60 return CPU_COUNT(
set);
63 for (
int i = 0; i < CPU_SETSIZE; ++i) {
64 if (CPU_ISSET(i,
set)) {
74 #elif defined(__FreeBSD__) 77 #include <sys/cpuset.h> 78 #include <sys/param.h> 112 if (hc != 0u && n >= hc) {
113 piranha_throw(std::invalid_argument,
"processor index is larger than the detected hardware concurrency");
115 #if defined(PIRANHA_HAVE_PTHREAD_AFFINITY) 116 unsigned cpu_setsize;
119 cpu_setsize =
safe_cast<
unsigned>(CPU_SETSIZE);
122 piranha_throw(std::runtime_error,
"numeric conversion error");
124 if (n >= cpu_setsize) {
125 piranha_throw(std::invalid_argument,
"processor index is larger than the maximum allowed value");
129 CPU_SET(n_int, &cpuset);
130 const int errno_ = ::pthread_setaffinity_np(::pthread_self(),
sizeof(cpuset), &cpuset);
132 piranha_throw(std::runtime_error,
"the call to pthread_setaffinity_np() failed");
134 #elif defined(__FreeBSD__) 135 unsigned cpu_setsize;
138 cpu_setsize =
safe_cast<
unsigned>(CPU_SETSIZE);
141 piranha_throw(std::runtime_error,
"numeric conversion error");
143 if (n >= cpu_setsize) {
144 piranha_throw(std::invalid_argument,
"processor index is larger than the maximum allowed value");
149 if (::cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
sizeof(cpuset), &cpuset) == -1) {
150 piranha_throw(std::runtime_error,
"the call to cpuset_setaffinity() failed");
152 #elif defined(_WIN32) 154 if (n >= static_cast<unsigned>(std::numeric_limits<DWORD_PTR>::digits)) {
155 piranha_throw(std::invalid_argument,
"processor index is larger than the maximum allowed value");
157 if (::SetThreadAffinityMask(::GetCurrentThread(), (DWORD_PTR)1 << n) == 0) {
158 piranha_throw(std::runtime_error,
"the call to SetThreadAffinityMask() failed");
182 #if defined(PIRANHA_HAVE_PTHREAD_AFFINITY) 185 const int errno_ = ::pthread_getaffinity_np(::pthread_self(),
sizeof(cpuset), &cpuset);
187 piranha_throw(std::runtime_error,
"the call to pthread_getaffinity_np() failed");
189 const int cpu_count = posix_cpu_count(&cpuset);
190 if (cpu_count == 0 || cpu_count > 1) {
191 return std::make_pair(
false, static_cast<unsigned>(0));
195 cpu_setsize =
safe_cast<
int>(CPU_SETSIZE);
197 piranha_throw(std::runtime_error,
"numeric conversion error");
199 for (
int i = 0; i < cpu_setsize; ++i) {
200 if (CPU_ISSET(i, &cpuset)) {
203 return std::make_pair(
true, static_cast<unsigned>(i));
207 #elif defined(__FreeBSD__) 210 const int errno_ = ::cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
sizeof(cpuset), &cpuset);
212 piranha_throw(std::runtime_error,
"the call to ::cpuset_getaffinity() failed");
216 cpu_setsize =
safe_cast<
int>(CPU_SETSIZE);
218 piranha_throw(std::runtime_error,
"numeric conversion error");
220 unsigned bound_cpus = 0;
222 for (
int i = 0; i < cpu_setsize; ++i) {
223 if (CPU_ISSET(i, &cpuset)) {
228 if (bound_cpus == 0 || bound_cpus > 1) {
229 return std::make_pair(
false, static_cast<unsigned>(0));
231 return std::make_pair(
true, static_cast<unsigned>(candidate));
233 #elif defined(_WIN32) 235 const DWORD_PTR original_affinity_mask = ::SetThreadAffinityMask(::GetCurrentThread(), (DWORD_PTR)1);
236 if (original_affinity_mask == 0) {
237 piranha_throw(std::runtime_error,
"the call to SetThreadAffinityMask() failed");
239 const unsigned cpu_setsize =
static_cast<unsigned>(std::numeric_limits<DWORD_PTR>::digits);
240 unsigned bound_cpus = 0, candidate = 0;
241 for (
unsigned i = 0; i < cpu_setsize; ++i) {
242 if (((DWORD_PTR)1 << i) & original_affinity_mask) {
248 if (::SetThreadAffinityMask(::GetCurrentThread(), original_affinity_mask) == 0) {
249 piranha_throw(std::runtime_error,
"the call to SetThreadAffinityMask() failed");
251 if (bound_cpus == 0 || bound_cpus > 1) {
252 return std::make_pair(
false, static_cast<unsigned>(0));
254 return std::make_pair(
true, candidate);
void bind_to_proc(unsigned n)
Bind thread to specific processor.
std::pair< bool, unsigned > bound_proc()
Query if current thread is bound to a processor.
#define piranha_throw(exception_type,...)
Exception-throwing macro.
Exception for functionality not implemented or not available on the current platform.
static unsigned get_hardware_concurrency()
Hardware concurrency.
Exception to signal failure in piranha::safe_cast().
safe_cast_type< To, From > safe_cast(const From &x)
Safe cast.