xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Linux/Procfs.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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()20 Expected<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)32 lldb_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()54 lldb_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