File: Procfs.cpp

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb11u2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,634,820 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (70 lines) | stat: -rw-r--r-- 2,377 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//===-- Procfs.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Procfs.h"
#include "lldb/Host/linux/Support.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Threading.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace process_linux;
using namespace llvm;

Expected<ArrayRef<uint8_t>> lldb_private::process_linux::GetProcfsCpuInfo() {
  static ErrorOr<std::unique_ptr<MemoryBuffer>> cpu_info_or_err =
      getProcFile("cpuinfo");

  if (!*cpu_info_or_err)
    cpu_info_or_err.getError();

  MemoryBuffer &buffer = **cpu_info_or_err;
  return arrayRefFromStringRef(buffer.getBuffer());
}

Expected<std::vector<cpu_id_t>>
lldb_private::process_linux::GetAvailableLogicalCoreIDs(StringRef cpuinfo) {
  SmallVector<StringRef, 8> lines;
  cpuinfo.split(lines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
  std::vector<cpu_id_t> logical_cores;

  for (StringRef line : lines) {
    std::pair<StringRef, StringRef> key_value = line.split(':');
    auto key = key_value.first.trim();
    auto val = key_value.second.trim();
    if (key == "processor") {
      cpu_id_t processor;
      if (val.getAsInteger(10, processor))
        return createStringError(
            inconvertibleErrorCode(),
            "Failed parsing the /proc/cpuinfo line entry: %s", line.data());
      logical_cores.push_back(processor);
    }
  }
  return logical_cores;
}

llvm::Expected<llvm::ArrayRef<cpu_id_t>>
lldb_private::process_linux::GetAvailableLogicalCoreIDs() {
  static std::optional<std::vector<cpu_id_t>> logical_cores_ids;
  if (!logical_cores_ids) {
    // We find the actual list of core ids by parsing /proc/cpuinfo
    Expected<ArrayRef<uint8_t>> cpuinfo = GetProcfsCpuInfo();
    if (!cpuinfo)
      return cpuinfo.takeError();

    Expected<std::vector<cpu_id_t>> cpu_ids = GetAvailableLogicalCoreIDs(
        StringRef(reinterpret_cast<const char *>(cpuinfo->data())));
    if (!cpu_ids)
      return cpu_ids.takeError();

    logical_cores_ids.emplace(std::move(*cpu_ids));
  }
  return *logical_cores_ids;
}