|
12 | 12 | #if defined(__APPLE__) |
13 | 13 | #include <sys/sysctl.h> |
14 | 14 | #elif defined(unix) || defined(__unix) || defined(__unix__) |
| 15 | +#include <sched.h> |
15 | 16 | #include <unistd.h> |
16 | 17 | #include <fstream> |
17 | 18 | #include <regex> |
| 19 | +#include <set> |
18 | 20 | #elif defined(_WIN32) || defined(_WIN64) |
19 | 21 | #include <windows.h> |
20 | 22 | #endif |
@@ -100,8 +102,12 @@ int CPU::Affinity() |
100 | 102 |
|
101 | 103 | return logical; |
102 | 104 | #elif defined(unix) || defined(__unix) || defined(__unix__) |
103 | | - long processors = sysconf(_SC_NPROCESSORS_ONLN); |
104 | | - return processors; |
| 105 | + cpu_set_t cs; |
| 106 | + CPU_ZERO(&cs); |
| 107 | + if (sched_getaffinity(0, sizeof(cs), &cs) != 0) |
| 108 | + return -1; |
| 109 | + |
| 110 | + return CPU_COUNT(&cs); |
105 | 111 | #elif defined(_WIN32) || defined(_WIN64) |
106 | 112 | SYSTEM_INFO si; |
107 | 113 | GetSystemInfo(&si); |
@@ -136,8 +142,22 @@ std::pair<int, int> CPU::TotalCores() |
136 | 142 |
|
137 | 143 | return std::make_pair(logical, physical); |
138 | 144 | #elif defined(unix) || defined(__unix) || defined(__unix__) |
139 | | - long processors = sysconf(_SC_NPROCESSORS_ONLN); |
140 | | - return std::make_pair(processors, processors); |
| 145 | + static std::regex pattern("core id(.*): (.*)"); |
| 146 | + |
| 147 | + std::set<int> cores; |
| 148 | + |
| 149 | + std::string line; |
| 150 | + std::ifstream stream("/proc/cpuinfo"); |
| 151 | + while (getline(stream, line)) |
| 152 | + { |
| 153 | + std::smatch matches; |
| 154 | + if (std::regex_match(line, matches, pattern)) |
| 155 | + cores.insert(atoi(matches[2].str().c_str())); |
| 156 | + } |
| 157 | + |
| 158 | + size_t logical = cores.size(); |
| 159 | + long physical = sysconf(_SC_NPROCESSORS_ONLN); |
| 160 | + return std::make_pair(logical, physical); |
141 | 161 | #elif defined(_WIN32) || defined(_WIN64) |
142 | 162 | BOOL allocated = FALSE; |
143 | 163 | PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pBuffer = nullptr; |
@@ -202,6 +222,12 @@ int64_t CPU::ClockSpeed() |
202 | 222 | if (sysctlbyname("hw.cpufrequency", &frequency, &size, nullptr, 0) == 0) |
203 | 223 | return frequency; |
204 | 224 |
|
| 225 | + // On Apple Silicon fallback to hw.tbfrequency and kern.clockrate.hz |
| 226 | + struct clockinfo clockrate; |
| 227 | + size_t clockrate_size = sizeof(clockrate); |
| 228 | + if ((sysctlbyname("hw.tbfrequency", &frequency, &frequency_size, NULL, 0) == 0) && (sysctlbyname("kern.clockrate", &clockrate, &clockrate_size, NULL, 0) == 0)) |
| 229 | + return frequency * clockrate.hz; |
| 230 | + |
205 | 231 | return -1; |
206 | 232 | #elif defined(unix) || defined(__unix) || defined(__unix__) |
207 | 233 | static std::regex pattern("cpu MHz(.*): (.*)"); |
|
0 commit comments