1 2 // Copyright Oliver Kowalke 2017. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #include "boost/fiber/numa/topology.hpp" 8 9 extern "C" { 10 #include <errno.h> 11 #include <sys/param.h> 12 #include <sys/cpuset.h> 13 } 14 15 #include <system_error> 16 17 #ifdef BOOST_HAS_ABI_HEADERS 18 # include BOOST_ABI_PREFIX 19 #endif 20 21 namespace boost { 22 namespace fibers { 23 namespace numa { 24 25 BOOST_FIBERS_DECL topology()26std::vector< node > topology() { 27 std::vector< node > topo; 28 cpuset_t mask; 29 CPU_ZERO( & mask); 30 if ( BOOST_UNLIKELY( 0 != ::cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_CPUSET, -1, sizeof( mask), & mask) ) ) { 31 throw std::system_error{ 32 std::error_code{ errno, std::system_category() }, 33 "::cpuset_getaffinity() failed" }; 34 } 35 node n; 36 n.id = 0; // FreeBSD does not support NUMA 37 for ( int cpu_id = 0; cpu_id < CPU_SETSIZE; ++cpu_id) { 38 if ( CPU_ISSET( cpu_id, & mask) ) { 39 n.logical_cpus.insert( static_cast< std::uint32_t >( cpu_id) ); 40 } 41 } 42 topo.push_back( n); 43 // fake NUMA distance 44 std::size_t size = topo.size(); 45 for ( auto & n : topo) { 46 for ( std::size_t i = 0; i < size; ++i) { 47 n.distance.push_back( n.id == i ? 10 : 20); 48 } 49 } 50 return topo; 51 } 52 53 }}} 54 55 #ifdef BOOST_HAS_ABI_HEADERS 56 # include BOOST_ABI_SUFFIX 57 #endif 58