Chromium Code Reviews| Index: components/memory_pressure/memory_pressure_stats_collector.h |
| diff --git a/components/memory_pressure/memory_pressure_stats_collector.h b/components/memory_pressure/memory_pressure_stats_collector.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..303ba3174214d68e68df83b4f19452741478b6f2 |
| --- /dev/null |
| +++ b/components/memory_pressure/memory_pressure_stats_collector.h |
| @@ -0,0 +1,111 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_ |
| +#define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_ |
| + |
| +#include "base/time/tick_clock.h" |
| +#include "components/memory_pressure/memory_pressure_listener.h" |
| + |
| +namespace memory_pressure { |
| + |
| +// Enumeration of UMA memory pressure levels. This needs to be kept in sync with |
| +// histograms.xml and the memory pressure levels defined in |
| +// MemoryPressureListener. Included in the header so that |
| +// UMA_MEMORY_PRESSURE_LEVEL_COUNT is available. |
| +enum MemoryPressureLevelUMA { |
| + UMA_MEMORY_PRESSURE_LEVEL_NONE = 0, |
| + UMA_MEMORY_PRESSURE_LEVEL_MODERATE = 1, |
| + UMA_MEMORY_PRESSURE_LEVEL_CRITICAL = 2, |
| + // This must be the last value in the enum. |
| + UMA_MEMORY_PRESSURE_LEVEL_COUNT, |
| +}; |
| + |
| +// Class that is responsible for collecting and eventually reporting memory |
| +// pressure statistics. |
| +// |
| +// On platforms with a polling memory pressure implementation the |
| +// UpdateStatistics function will be invoked every time the pressure is polled. |
| +// On non-polling platforms (Mac, Android) it will be invoked on a periodic |
| +// timer, and at the moment of pressure level changes. |
| +class MemoryPressureStatsCollector { |
| + public: |
| + using MemoryPressureLevel = MemoryPressureListener::MemoryPressureLevel; |
| + |
| + // An abstract reporting delegate used as a testing seam. |
| + class ReportingDelegate; |
| + // The default reporting delegate, which delivers stats via UMA. |
| + class UmaReportingDelegate; |
| + |
| + // The provided |reporting_delegate| and |tick_clock| must outlive this class. |
| + MemoryPressureStatsCollector(ReportingDelegate* reporting_delegate, |
| + base::TickClock* tick_clock); |
| + |
| + // This is to be called periodically to ensure that up to date statistics |
| + // have been reported. |
| + void UpdateStatistics(MemoryPressureLevel current_pressure_level); |
| + |
| + private: |
| + friend class TestMemoryPressureStatsCollector; |
| + |
| + // The reporting delegate in use. This indirection creates a test seam. |
| + ReportingDelegate* reporting_delegate_; |
| + |
| + // The tick clock in use. This class is intended to be owned by a class with |
| + // a tick clock, and ownership remains there. Also intended as a test seam. |
| + base::TickClock* tick_clock_; |
| + |
| + // Buckets of time that have been spent in different pressure levels, but |
| + // not yet reported. At every call to UpdateStatistics these buckets will be |
| + // drained as much as possible and reported. |
| + base::TimeDelta unreported_cumulative_time_[UMA_MEMORY_PRESSURE_LEVEL_COUNT]; |
| + |
| + // The last observed pressure level and the time at which it was observed, and |
| + // the time when this pressure level started. |
| + MemoryPressureLevel last_pressure_level_; |
| + base::TimeTicks last_update_time_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MemoryPressureStatsCollector); |
| +}; |
| + |
| +// An abstract reporting delegate used as a testing seam. |
| +class MemoryPressureStatsCollector::ReportingDelegate { |
|
grt (UTC plus 2)
2015/09/04 19:46:19
instead of introducing a layer between MPSC and UM
chrisha
2015/09/04 20:31:24
I'm not averse to this, I just didn't even know it
|
| + public: |
| + ReportingDelegate() {} |
|
grt (UTC plus 2)
2015/09/04 19:46:19
nit: make the ctor and dtors protected via:
prote
chrisha
2015/09/04 20:31:24
Grrr... I'm still not used to "= default" (despite
|
| + virtual ~ReportingDelegate() {} |
| + |
| + // Sends a report that the system spent the given number of |seconds| at the |
| + // given |pressure_level|, cumulatively (potentially split across multiple |
| + // pressure changes since the last report was sent). |
| + virtual void ReportCumulativeTime(MemoryPressureLevel pressure_level, |
| + int seconds) = 0; |
| + |
| + // Reports a memory pressure level change. |
| + virtual void ReportLevelChange(MemoryPressureLevel old_pressure_level, |
| + MemoryPressureLevel new_pressure_level) = 0; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(ReportingDelegate); |
| +}; |
| + |
| +// The default reporting delegate, which delivers stats via UMA. |
| +class MemoryPressureStatsCollector::UmaReportingDelegate |
| + : public ReportingDelegate { |
| + public: |
| + UmaReportingDelegate() {} |
|
grt (UTC plus 2)
2015/09/04 19:46:19
= default;
chrisha
2015/09/08 15:47:15
No longer applicable.
|
| + ~UmaReportingDelegate() override {} |
|
grt (UTC plus 2)
2015/09/04 19:46:19
hmm, can you = default; here as well rather than o
chrisha
2015/09/08 15:47:14
No longer applicable.
|
| + |
| + // ReportingDelegate: |
| + void ReportCumulativeTime(MemoryPressureLevel pressure_level, |
| + int seconds) override; |
| + void ReportLevelChange(MemoryPressureLevel old_pressure_level, |
| + MemoryPressureLevel new_pressure_level) override; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(UmaReportingDelegate); |
| +}; |
| + |
| +} // namespace memory_pressure |
| + |
| +#endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_ |