cpu_probe_win.cc 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2022 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_win.h"
  5. #include "base/logging.h"
  6. #include "base/memory/ptr_util.h"
  7. namespace device {
  8. // static
  9. std::unique_ptr<CpuProbeWin> CpuProbeWin::Create() {
  10. return base::WrapUnique(new CpuProbeWin());
  11. }
  12. CpuProbeWin::CpuProbeWin() {
  13. DETACH_FROM_SEQUENCE(sequence_checker_);
  14. }
  15. CpuProbeWin::~CpuProbeWin() {
  16. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  17. }
  18. void CpuProbeWin::Update() {
  19. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  20. const auto& result = GetPdhData();
  21. if (result.has_value()) {
  22. last_sample_ = std::move(result.value());
  23. } else {
  24. last_sample_ = kUnsupportedValue;
  25. LOG(ERROR) << result.error();
  26. }
  27. }
  28. PressureSample CpuProbeWin::LastSample() {
  29. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  30. return last_sample_;
  31. }
  32. base::expected<PressureSample, std::string> CpuProbeWin::GetPdhData() {
  33. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  34. PDH_STATUS pdh_status;
  35. if (!cpu_query_.is_valid()) {
  36. cpu_query_ = ScopedPdhQuery::Create();
  37. if (!cpu_query_.is_valid())
  38. return base::unexpected("PdhOpenQuery failed.");
  39. pdh_status = PdhAddEnglishCounter(cpu_query_.get(),
  40. L"\\Processor(_Total)\\% Processor Time",
  41. NULL, &cpu_percent_utilization_);
  42. if (pdh_status != ERROR_SUCCESS) {
  43. cpu_query_.reset();
  44. return base::unexpected("PdhAddEnglishCounter failed.");
  45. }
  46. }
  47. pdh_status = PdhCollectQueryData(cpu_query_.get());
  48. if (pdh_status != ERROR_SUCCESS)
  49. return base::unexpected("PdhCollectQueryData failed.");
  50. PDH_FMT_COUNTERVALUE counter_value;
  51. pdh_status = PdhGetFormattedCounterValue(
  52. cpu_percent_utilization_, PDH_FMT_DOUBLE, NULL, &counter_value);
  53. if (pdh_status != ERROR_SUCCESS)
  54. return base::unexpected("PdhGetFormattedCounterValue failed.");
  55. return PressureSample{counter_value.doubleValue / 100.0};
  56. }
  57. } // namespace device