• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*  Copyright 2019 Rene Rivera
2  *  Distributed under the Boost Software License, Version 1.0.
3  *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4  */
5 
6 #include "sysinfo.h"
7 #include "jam.h"
8 #include "output.h"
9 
10 #include <thread>
11 
12 #if defined(OS_MACOSX)
13 #include <sys/types.h>
14 #include <sys/sysctl.h>
15 #endif
16 
17 #if !defined(OS_NT)
18 #include <unistd.h>
19 #endif
20 
21 #if defined(OS_LINUX)
22 // Need to define this in case it's not as that's the only way to get the
23 // sched_* APIs.
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE
26 #endif
27 #include <sched.h>
28 #endif
29 
30 
system_info()31 b2::system_info::system_info()
32 {
33 }
34 
35 namespace
36 {
macosx_physicalcpu()37     unsigned int macosx_physicalcpu()
38     {
39         #if defined(OS_MACOSX)
40         int out_hw_ncpu = 0;
41         size_t len_hw_ncpu = sizeof(out_hw_ncpu);
42         int result = ::sysctlbyname(
43             "hw.physicalcpu", &out_hw_ncpu, &len_hw_ncpu, nullptr, 0);
44         if (result == 0) return out_hw_ncpu;
45         #endif
46         return 0;
47     }
48 
macosx_logicalcpu()49     unsigned int macosx_logicalcpu()
50     {
51         #if defined(OS_MACOSX)
52         int out_hw_ncpu = 0;
53         size_t len_hw_ncpu = sizeof(out_hw_ncpu);
54         int result = ::sysctlbyname(
55             "hw.logicalcpu", &out_hw_ncpu, &len_hw_ncpu, nullptr, 0);
56         if (result == 0) return out_hw_ncpu;
57         #endif
58         return 0;
59     }
60 
sched_affinity_cpu_count()61     unsigned int sched_affinity_cpu_count()
62     {
63         #if defined(CPU_COUNT_S)
64         ::cpu_set_t cpu_set;
65         if (::sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set) == 0)
66         {
67             return CPU_COUNT_S(sizeof(cpu_set_t), &cpu_set);
68         }
69         #endif
70         return 0;
71     }
72 
sysconf_nprocs_configured()73     unsigned int sysconf_nprocs_configured()
74     {
75         #if defined(_SC_NPROCESSORS_ONLN)
76         return ::sysconf(_SC_NPROCESSORS_CONF);
77         #else
78         return 0;
79         #endif
80     }
81 
sysconf_nprocs_online()82     unsigned int sysconf_nprocs_online()
83     {
84         #if defined(_SC_NPROCESSORS_ONLN)
85         return ::sysconf(_SC_NPROCESSORS_ONLN);
86         #else
87         return 0;
88         #endif
89     }
90 
std_thread_hardware_concurrency()91     unsigned int std_thread_hardware_concurrency()
92     {
93         return std::thread::hardware_concurrency();
94     }
95 }
96 
cpu_core_count()97 unsigned int b2::system_info::cpu_core_count()
98 {
99     if (cpu_core_count_ == 0)
100     {
101         cpu_thread_count_ = macosx_physicalcpu();
102     }
103     if (cpu_thread_count_ == 0)
104     {
105         cpu_thread_count_ = sysconf_nprocs_configured();
106     }
107     if (cpu_core_count_ <= 0)
108     {
109         cpu_core_count_ = 1;
110     }
111     return cpu_core_count_;
112 }
113 
cpu_thread_count()114 unsigned int b2::system_info::cpu_thread_count()
115 {
116     if (cpu_thread_count_ == 0)
117     {
118         cpu_thread_count_ = macosx_logicalcpu();
119     }
120     if (cpu_thread_count_ == 0)
121     {
122         cpu_thread_count_ = sched_affinity_cpu_count();
123     }
124     if (cpu_thread_count_ == 0)
125     {
126         cpu_thread_count_ = sysconf_nprocs_online();
127     }
128     if (cpu_thread_count_ == 0)
129     {
130         cpu_thread_count_ = std_thread_hardware_concurrency();
131     }
132     if (cpu_thread_count_ == 0)
133     {
134         cpu_thread_count_ = cpu_core_count();
135     }
136     return cpu_thread_count_;
137 }
138