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