• 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/lgrp_user.h>
12 }
13 
14 #include <system_error>
15 
16 #ifdef BOOST_HAS_ABI_HEADERS
17 # include BOOST_ABI_PREFIX
18 #endif
19 
20 namespace {
21 
explore(std::vector<boost::fibers::numa::node> & topo,lgrp_cookie_t cookie,lgrp_id_t node)22 void explore( std::vector< boost::fibers::numa::node > & topo, lgrp_cookie_t cookie, lgrp_id_t node) {
23     int size = ::lgrp_cpus( cookie, node, nullptr, 0, LGRP_CONTENT_HIERARCHY);
24     if ( -1 == size) {
25         return;
26     }
27     // is node a NUMA Node?
28     if ( 0 < ::lgrp_mem_size( cookie, node, LGRP_MEM_SZ_INSTALLED, LGRP_CONTENT_DIRECT) ) {
29         std::vector< processorid_t > cpus;
30         cpus.resize( size);
31         ::lgrp_cpus( cookie, node, cpus.data(), size, LGRP_CONTENT_HIERARCHY);
32         boost::fibers::numa::node n;
33         n.id = static_cast< std::uint32_t >( node);
34         for ( auto cpu_id : cpus) {
35             n.logical_cpus.insert( static_cast< std::uint32_t >( cpu_id) );
36         }
37         topo.push_back( n);
38     }
39     size = ::lgrp_children( cookie, node, nullptr, 0);
40     std::vector< lgrp_id_t > nodes;
41     nodes.resize( size);
42     ::lgrp_children( cookie, node, nodes.data(), size);
43     for ( auto node : nodes) {
44         explore( topo, cookie, node);
45     }
46 }
47 
48 }
49 
50 namespace boost {
51 namespace fibers {
52 namespace numa {
53 
54 BOOST_FIBERS_DECL
topology()55 std::vector< node > topology() {
56     std::vector< node > topo;
57     lgrp_cookie_t cookie = ::lgrp_init( LGRP_VIEW_OS);
58     if ( BOOST_UNLIKELY( LGRP_COOKIE_NONE == cookie) ) {
59         throw std::system_error{
60                 std::error_code{ errno, std::system_category() },
61                 "lprp_init() failed" };
62     }
63     lgrp_id_t root = ::lgrp_root( cookie);
64     explore( topo, cookie, root);
65     ::lgrp_fini( cookie);
66     // fake NUMA distance
67     std::size_t size = topo.size();
68     for ( auto & n : topo) {
69         for ( std::size_t i = 0; i < size; ++i) {
70             n.distance.push_back( n.id == i ? 10 : 20);
71         }
72     }
73     return topo;
74 }
75 
76 }}}
77 
78 #ifdef BOOST_HAS_ABI_HEADERS
79 # include BOOST_ABI_SUFFIX
80 #endif
81