platform_collector.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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/platform_collector.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback_forward.h"
  8. #include "base/location.h"
  9. #include "base/memory/scoped_refptr.h"
  10. #include "base/sequence_checker.h"
  11. #include "base/task/sequenced_task_runner.h"
  12. #include "base/task/task_traits.h"
  13. #include "base/task/thread_pool.h"
  14. #include "base/threading/sequenced_task_runner_handle.h"
  15. #include "base/time/time.h"
  16. #include "services/device/compute_pressure/cpu_probe.h"
  17. #include "services/device/compute_pressure/pressure_sample.h"
  18. namespace device {
  19. namespace {
  20. scoped_refptr<base::SequencedTaskRunner> CreateProbeTaskRunner() {
  21. // While some samples can be collected without doing blocking operations,
  22. // this isn't guaranteed on all operating systems.
  23. return base::ThreadPool::CreateSequencedTaskRunner(
  24. {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
  25. base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
  26. }
  27. } // namespace
  28. PlatformCollector::PlatformCollector(
  29. std::unique_ptr<CpuProbe> probe,
  30. base::TimeDelta sampling_interval,
  31. base::RepeatingCallback<void(PressureSample)> sampling_callback)
  32. : probe_task_runner_(CreateProbeTaskRunner()),
  33. probe_(std::move(probe)),
  34. sampling_interval_(sampling_interval),
  35. sampling_callback_(std::move(sampling_callback)) {
  36. DCHECK(sampling_callback_);
  37. }
  38. PlatformCollector::~PlatformCollector() {
  39. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  40. probe_task_runner_->DeleteSoon(FROM_HERE, std::move(probe_));
  41. }
  42. void PlatformCollector::EnsureStarted() {
  43. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  44. DCHECK(has_probe()) << __func__
  45. << " should not be called if has_probe() returns false";
  46. DCHECK(probe_);
  47. if (timer_.IsRunning())
  48. return;
  49. DCHECK(!got_probe_baseline_) << "got_probe_baseline_ incorrectly reset";
  50. // Schedule the first CpuProbe update right away. This update's result will
  51. // not be reported, thanks to the accounting done by `got_probe_baseline_`.
  52. UpdateProbe();
  53. // base::Unretained usage is safe here because base::RepeatingTimer guarantees
  54. // that its callback will not be called after it goes out of scope.
  55. timer_.Start(FROM_HERE, sampling_interval_,
  56. base::BindRepeating(&PlatformCollector::UpdateProbe,
  57. base::Unretained(this)));
  58. }
  59. void PlatformCollector::Stop() {
  60. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  61. timer_.AbandonAndStop();
  62. got_probe_baseline_ = false;
  63. }
  64. void PlatformCollector::UpdateProbe() {
  65. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  66. DCHECK(has_probe());
  67. // Raw CpuProbe pointer usage is safe here because the CpuProbe instance will
  68. // be destroyed by queueing a task on `probe_task_runner_`. That task must get
  69. // queued after this task.
  70. probe_task_runner_->PostTaskAndReplyWithResult(
  71. FROM_HERE,
  72. base::BindOnce(
  73. [](CpuProbe* probe) -> PressureSample {
  74. probe->Update();
  75. return probe->LastSample();
  76. },
  77. probe_.get()),
  78. base::BindOnce(&PlatformCollector::DidUpdateProbe,
  79. weak_factory_.GetWeakPtr()));
  80. }
  81. void PlatformCollector::DidUpdateProbe(PressureSample sample) {
  82. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  83. // Don't report the update result if Stop() was called.
  84. if (!timer_.IsRunning())
  85. return;
  86. // Don't report the first update result.
  87. if (!got_probe_baseline_) {
  88. got_probe_baseline_ = true;
  89. return;
  90. }
  91. sampling_callback_.Run(sample);
  92. }
  93. } // namespace device