/* -*- c++ -*- */ /* * Copyright 2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * GNU Radio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) #include namespace gruel { gr_thread_t get_current_thread_id() { return GetCurrentThread(); } void thread_bind_to_processor(int n) { std::vector mask(1, n); thread_bind_to_processor(get_current_thread_id(), mask); } void thread_bind_to_processor(const std::vector &mask) { thread_bind_to_processor(get_current_thread_id(), mask); } void thread_bind_to_processor(gr_thread_t thread, int n) { std::vector mask(1, n); thread_bind_to_processor(thread, mask); } void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) { //DWORD_PTR mask = (1 << n); DWORD_PTR dword_mask = 0; std::vector _mask = mask; std::vector::iterator itr; for(itr = _mask.begin(); itr != _mask.end(); itr++) dword_mask |= (1 << (*itr)); DWORD_PTR ret = SetThreadAffinityMask(thread, dword_mask); if(ret == 0) { std::stringstream s; s << "thread_bind_to_processor failed with error: " << GetLastError() << std::endl; throw std::runtime_error(s.str()); } } void thread_unbind() { thread_unbind(get_current_thread_id()); } void thread_unbind(gr_thread_t thread) { DWORD_PTR dword_mask = sizeof(DWORD_PTR) - 1; DWORD_PTR ret = SetThreadAffinityMask(thread, dword_mask); if(ret == 0) { std::stringstream s; s << "thread_unbind failed with error: " << GetLastError() << std::endl; throw std::runtime_error(s.str()); } } } /* namespace gruel */ #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) namespace gruel { gr_thread_t get_current_thread_id() { // Not implemented on OSX } void thread_bind_to_processor(int n) { // Not implemented on OSX } void thread_bind_to_processor(gr_thread_t thread, int n) { // Not implemented on OSX } void thread_bind_to_processor(const std::vector &mask) { // Not implemented on OSX } void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) { // Not implemented on OSX } void thread_unbind() { // Not implemented on OSX } void thread_unbind(gr_thread_t thread) { // Not implemented on OSX } } /* namespace gruel */ #else #include #include #include namespace gruel { gr_thread_t get_current_thread_id() { return pthread_self(); } void thread_bind_to_processor(int n) { std::vector mask(1, n); thread_bind_to_processor(get_current_thread_id(), mask); } void thread_bind_to_processor(const std::vector &mask) { thread_bind_to_processor(get_current_thread_id(), mask); } void thread_bind_to_processor(gr_thread_t thread, int n) { std::vector mask(1, n); thread_bind_to_processor(thread, mask); } void thread_bind_to_processor(gr_thread_t thread, const std::vector &mask) { cpu_set_t set; size_t len = sizeof(cpu_set_t); std::vector _mask = mask; std::vector::iterator itr; CPU_ZERO(&set); for(itr = _mask.begin(); itr != _mask.end(); itr++) CPU_SET(*itr, &set); int ret = pthread_setaffinity_np(thread, len, &set); if(ret != 0) { std::stringstream s; s << "thread_bind_to_processor failed with error: " << ret << std::endl; throw std::runtime_error(s.str()); } } void thread_unbind() { thread_unbind(get_current_thread_id()); } void thread_unbind(gr_thread_t thread) { cpu_set_t set; size_t len = sizeof(cpu_set_t); CPU_ZERO(&set); long ncpus = sysconf(_SC_NPROCESSORS_ONLN); for(long n = 0; n < ncpus; n++) { CPU_SET(n, &set); } int ret = pthread_setaffinity_np(thread, len, &set); if(ret != 0) { std::stringstream s; s << "thread_unbind failed with error: " << ret << std::endl; throw std::runtime_error(s.str()); } } } /* namespace gruel */ #endif