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 11 #include "lldb/Host/linux/Support.h" 12 #include "llvm/Support/MemoryBuffer.h" 13 14 using namespace lldb; 15 using namespace lldb_private; 16 using namespace process_linux; 17 using namespace llvm; 18 19 Expected<ArrayRef<uint8_t>> lldb_private::process_linux::GetProcfsCpuInfo() { 20 static Optional<std::vector<uint8_t>> cpu_info; 21 if (!cpu_info) { 22 auto buffer_or_error = errorOrToExpected(getProcFile("cpuinfo")); 23 if (!buffer_or_error) 24 return buffer_or_error.takeError(); 25 MemoryBuffer &buffer = **buffer_or_error; 26 cpu_info = std::vector<uint8_t>( 27 reinterpret_cast<const uint8_t *>(buffer.getBufferStart()), 28 reinterpret_cast<const uint8_t *>(buffer.getBufferEnd())); 29 } 30 return *cpu_info; 31 } 32 33 Expected<std::vector<core_id_t>> 34 lldb_private::process_linux::GetAvailableLogicalCoreIDs(StringRef cpuinfo) { 35 SmallVector<StringRef, 8> lines; 36 cpuinfo.split(lines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); 37 std::vector<core_id_t> logical_cores; 38 39 for (StringRef line : lines) { 40 std::pair<StringRef, StringRef> key_value = line.split(':'); 41 auto key = key_value.first.trim(); 42 auto val = key_value.second.trim(); 43 if (key == "processor") { 44 core_id_t processor; 45 if (val.getAsInteger(10, processor)) 46 return createStringError( 47 inconvertibleErrorCode(), 48 "Failed parsing the /proc/cpuinfo line entry: %s", line.data()); 49 logical_cores.push_back(processor); 50 } 51 } 52 return logical_cores; 53 } 54 55 llvm::Expected<llvm::ArrayRef<core_id_t>> 56 lldb_private::process_linux::GetAvailableLogicalCoreIDs() { 57 static Optional<std::vector<core_id_t>> logical_cores_ids; 58 if (!logical_cores_ids) { 59 // We find the actual list of core ids by parsing /proc/cpuinfo 60 Expected<ArrayRef<uint8_t>> cpuinfo = GetProcfsCpuInfo(); 61 if (!cpuinfo) 62 return cpuinfo.takeError(); 63 64 Expected<std::vector<core_id_t>> core_ids = GetAvailableLogicalCoreIDs( 65 StringRef(reinterpret_cast<const char *>(cpuinfo->data()))); 66 if (!core_ids) 67 return core_ids.takeError(); 68 69 logical_cores_ids.emplace(std::move(*core_ids)); 70 } 71 return *logical_cores_ids; 72 } 73