1 //===-- Procfs.cpp --------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Procfs.h" 10 #include "lldb/Host/linux/Support.h" 11 #include "llvm/Support/MemoryBuffer.h" 12 #include "llvm/Support/Threading.h" 13 #include <optional> 14 15 using namespace lldb; 16 using namespace lldb_private; 17 using namespace process_linux; 18 using namespace llvm; 19 GetProcfsCpuInfo()20Expected<ArrayRef<uint8_t>> lldb_private::process_linux::GetProcfsCpuInfo() { 21 static ErrorOr<std::unique_ptr<MemoryBuffer>> cpu_info_or_err = 22 getProcFile("cpuinfo"); 23 24 if (!*cpu_info_or_err) 25 cpu_info_or_err.getError(); 26 27 MemoryBuffer &buffer = **cpu_info_or_err; 28 return arrayRefFromStringRef(buffer.getBuffer()); 29 } 30 31 Expected<std::vector<cpu_id_t>> GetAvailableLogicalCoreIDs(StringRef cpuinfo)32lldb_private::process_linux::GetAvailableLogicalCoreIDs(StringRef cpuinfo) { 33 SmallVector<StringRef, 8> lines; 34 cpuinfo.split(lines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); 35 std::vector<cpu_id_t> logical_cores; 36 37 for (StringRef line : lines) { 38 std::pair<StringRef, StringRef> key_value = line.split(':'); 39 auto key = key_value.first.trim(); 40 auto val = key_value.second.trim(); 41 if (key == "processor") { 42 cpu_id_t processor; 43 if (val.getAsInteger(10, processor)) 44 return createStringError( 45 inconvertibleErrorCode(), 46 "Failed parsing the /proc/cpuinfo line entry: %s", line.data()); 47 logical_cores.push_back(processor); 48 } 49 } 50 return logical_cores; 51 } 52 53 llvm::Expected<llvm::ArrayRef<cpu_id_t>> GetAvailableLogicalCoreIDs()54lldb_private::process_linux::GetAvailableLogicalCoreIDs() { 55 static std::optional<std::vector<cpu_id_t>> logical_cores_ids; 56 if (!logical_cores_ids) { 57 // We find the actual list of core ids by parsing /proc/cpuinfo 58 Expected<ArrayRef<uint8_t>> cpuinfo = GetProcfsCpuInfo(); 59 if (!cpuinfo) 60 return cpuinfo.takeError(); 61 62 Expected<std::vector<cpu_id_t>> cpu_ids = GetAvailableLogicalCoreIDs( 63 StringRef(reinterpret_cast<const char *>(cpuinfo->data()))); 64 if (!cpu_ids) 65 return cpu_ids.takeError(); 66 67 logical_cores_ids.emplace(std::move(*cpu_ids)); 68 } 69 return *logical_cores_ids; 70 } 71