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
GetProcfsCpuInfo()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<cpu_id_t>>
GetAvailableLogicalCoreIDs(StringRef cpuinfo)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<cpu_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 cpu_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<cpu_id_t>>
GetAvailableLogicalCoreIDs()56 lldb_private::process_linux::GetAvailableLogicalCoreIDs() {
57 static Optional<std::vector<cpu_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<cpu_id_t>> cpu_ids = GetAvailableLogicalCoreIDs(
65 StringRef(reinterpret_cast<const char *>(cpuinfo->data())));
66 if (!cpu_ids)
67 return cpu_ids.takeError();
68
69 logical_cores_ids.emplace(std::move(*cpu_ids));
70 }
71 return *logical_cores_ids;
72 }
73