cpu_probe_linux.cc 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/device/compute_pressure/cpu_probe_linux.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/files/file_path.h"
  9. #include "base/files/file_util.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "base/sequence_checker.h"
  12. #include "services/device/compute_pressure/procfs_stat_cpu_parser.h"
  13. namespace device {
  14. // static
  15. std::unique_ptr<CpuProbeLinux> CpuProbeLinux::Create() {
  16. return base::WrapUnique(
  17. new CpuProbeLinux(base::FilePath(ProcfsStatCpuParser::kProcfsStatPath)));
  18. }
  19. // static
  20. std::unique_ptr<CpuProbeLinux> CpuProbeLinux::CreateForTesting(
  21. base::FilePath procfs_stat_path) {
  22. return base::WrapUnique(new CpuProbeLinux(std::move(procfs_stat_path)));
  23. }
  24. CpuProbeLinux::CpuProbeLinux(base::FilePath procfs_stat_path)
  25. : stat_parser_(std::move(procfs_stat_path)) {
  26. DETACH_FROM_SEQUENCE(sequence_checker_);
  27. }
  28. CpuProbeLinux::~CpuProbeLinux() = default;
  29. void CpuProbeLinux::Update() {
  30. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  31. stat_parser_.Update();
  32. const std::vector<CoreTimes>& per_core_times = stat_parser_.core_times();
  33. double utilization_sum = 0.0;
  34. int utilization_cores = 0;
  35. for (size_t i = 0; i < per_core_times.size(); ++i) {
  36. DCHECK_GE(last_per_core_times_.size(), i);
  37. const CoreTimes& core_times = per_core_times[i];
  38. if (last_per_core_times_.size() == i) {
  39. InitializeCore(i, core_times);
  40. continue;
  41. }
  42. double core_utilization =
  43. core_times.TimeUtilization(last_per_core_times_[i]);
  44. if (core_utilization >= 0) {
  45. // Only overwrite `last_per_core_times_` if the /proc/stat counters are
  46. // monotonically increasing. Otherwise, discard the measurement.
  47. last_per_core_times_[i] = core_times;
  48. utilization_sum += core_utilization;
  49. ++utilization_cores;
  50. }
  51. }
  52. if (utilization_cores > 0) {
  53. last_sample_.cpu_utilization = utilization_sum / utilization_cores;
  54. } else {
  55. last_sample_ = kUnsupportedValue;
  56. }
  57. }
  58. PressureSample CpuProbeLinux::LastSample() {
  59. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  60. return last_sample_;
  61. }
  62. void CpuProbeLinux::InitializeCore(size_t core_index,
  63. const CoreTimes& initial_core_times) {
  64. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  65. DCHECK_EQ(last_per_core_times_.size(), core_index);
  66. last_per_core_times_.push_back(initial_core_times);
  67. }
  68. } // namespace device