• 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