| 42 | #endif |
| 43 | |
| 44 | int32_t get_num_physical_cores() { |
| 45 | #ifdef __linux__ |
| 46 | // enumerate the set of thread siblings, num entries is num cores |
| 47 | std::unordered_set<std::string> siblings; |
| 48 | for (uint32_t cpu=0; cpu < UINT32_MAX; ++cpu) { |
| 49 | std::ifstream thread_siblings("/sys/devices/system/cpu" |
| 50 | + std::to_string(cpu) + "/topology/thread_siblings"); |
| 51 | if (!thread_siblings.is_open()) { |
| 52 | break; // no more cpus |
| 53 | } |
| 54 | std::string line; |
| 55 | if (std::getline(thread_siblings, line)) { |
| 56 | siblings.insert(line); |
| 57 | } |
| 58 | } |
| 59 | if (!siblings.empty()) { |
| 60 | return static_cast<int32_t>(siblings.size()); |
| 61 | } |
| 62 | #elif defined(__APPLE__) && defined(__MACH__) |
| 63 | int32_t num_physical_cores; |
| 64 | size_t len = sizeof(num_physical_cores); |
| 65 | int result = sysctlbyname("hw.perflevel0.physicalcpu", &num_physical_cores, &len, NULL, 0); |
| 66 | if (result == 0) { |
| 67 | return num_physical_cores; |
| 68 | } |
| 69 | result = sysctlbyname("hw.physicalcpu", &num_physical_cores, &len, NULL, 0); |
| 70 | if (result == 0) { |
| 71 | return num_physical_cores; |
| 72 | } |
| 73 | #elif defined(_WIN32) |
| 74 | //TODO: Implement |
| 75 | #endif |
| 76 | unsigned int n_threads = std::thread::hardware_concurrency(); |
| 77 | return n_threads > 0 ? (n_threads <= 4 ? n_threads : n_threads / 2) : 4; |
| 78 | } |
| 79 | |
| 80 | void process_escapes(std::string& input) { |
| 81 | std::size_t input_len = input.length(); |