• 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/mpctl.h>
12 #include <sys/types.h>
13 #include <types.h>
14 }
15 
16 #include <map>
17 #include <system_error>
18 
19 #ifdef BOOST_HAS_ABI_HEADERS
20 # include BOOST_ABI_PREFIX
21 #endif
22 
23 namespace boost {
24 namespace fibers {
25 namespace numa {
26 
27 BOOST_FIBERS_DECL
topology()28 std::vector< node > topology() {
29     std::vector< node > topo;
30     // HP/UX has NUMA enabled
31     if ( 1 == ::sysconf( _SC_CCNUMA_SUPPORT) ) {
32         std::map< std::uint32_t, node > map;
33         // enumerate CPU sets
34         int cpu_id = ::mpctl( MPC_GETFIRSTSPU_SYS, 0, 0);
35         while ( -1 != cpu_id) {
36             int node_id = ::mpctl( MPC_SPUTOLDOM, cpu_id, 0);
37             if ( BOOST_UNLIKELY( -1 == node_id) ) {
38                 throw std::system_errors{
39                         std::error_codes{ errno, std::system_category() },
40                         "mpctl() failed" };
41             }
42             map[id].id = static_cast< std::uint32_t >( node_id);
43             map[id].logical_cpus.insert( static_cast< std::uint32_t >( cpu_id) );
44             cpu_id = ::mpctl( MPC_GETNEXTSPU_SYS, cpu_id, 0);
45         }
46         for ( auto entry : map) {
47             topo.push_back( entry.second);
48         }
49     }
50     // fake NUMA distance
51     std::size_t size = topo.size();
52     for ( auto & n : topo) {
53         for ( std::size_t i = 0; i < size; ++i) {
54             n.distance.push_back( n.id == i ? 10 : 20);
55         }
56     }
57     return topo;
58 }
59 
60 }}}
61 
62 #ifdef BOOST_HAS_ABI_HEADERS
63 # include BOOST_ABI_SUFFIX
64 #endif
65