• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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