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/rset.h> 12 #include <sys/types.h> 13 } 14 15 #include <system_error> 16 17 #ifdef BOOST_HAS_ABI_HEADERS 18 # include BOOST_ABI_PREFIX 19 #endif 20 21 namespace { 22 explore(int sdl,std::vector<boost::fibers::numa::node> & topo)23 void explore( int sdl, std::vector< boost::fibers::numa::node > & topo) { 24 rsethandle_t rset = ::rs_alloc( RS_PARTITION); 25 rsethandle_t rad = ::rs_alloc( RS_EMPTY); 26 int maxnodes = ::rs_numrads( rset, sdl, 0); 27 if ( BOOST_UNLIKELY( -1 == maxnodes) ) { 28 throw std::system_error{ 29 std::error_code{ errno, std::system_category() }, 30 "rs_numrads() failed" }; 31 } 32 for ( int node_id = 0; node_id < maxnodes; ++node_id) { 33 if ( ::rs_getrad( rset, rad, sdl, node_id, 0) ) { 34 continue; 35 } 36 if ( ! ::rs_getinfo( rad, R_NUMPROCS, 0) ) { 37 continue; 38 } 39 boost::fibers::numa::node n; 40 n.id = static_cast< std::uint32_t >( node_id); 41 int maxcpus = ::rs_getinfo( rad, R_MAXPROCS, 0); 42 for ( int cpu_id = 0; cpu_id < maxcpus; ++cpu_id) { 43 if ( ::rs_op( RS_TESTRESOURCE, rad, nullptr, R_PROCS, cpu_id) ) { 44 n.logical_cpus.insert( static_cast< std::uint32_t >( cpu_id) ); 45 } 46 } 47 topo.push_back( n); 48 } 49 ::rs_free( rset); 50 ::rs_free( rad); 51 } 52 53 } 54 55 namespace boost { 56 namespace fibers { 57 namespace numa { 58 59 BOOST_FIBERS_DECL topology()60 std::vector< node > topology() { 61 std::vector< node > topo; 62 int maxlevel = ::rs_getinfo( nullptr, R_MAXSDL, 0); 63 for ( int i = 0; i <= maxlevel; ++i) { 64 if ( i == ::rs_getinfo( nullptr, R_MCMSDL, 0) ) { 65 explore( i, topo); 66 break; 67 } 68 } 69 // fake NUMA distance 70 std::size_t size = topo.size(); 71 for ( auto & n : topo) { 72 for ( std::size_t i = 0; i < size; ++i) { 73 n.distance.push_back( n.id == i ? 10 : 20); 74 } 75 } 76 return topo; 77 } 78 79 }}} 80 81 #ifdef BOOST_HAS_ABI_HEADERS 82 # include BOOST_ABI_SUFFIX 83 #endif 84