| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H | 5 #ifndef BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H |
| 6 #define BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H | 6 #define BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H |
| 7 | 7 |
| 8 #include <memory> | 8 #include <stdint.h> |
| 9 |
| 10 #include <vector> |
| 9 | 11 |
| 10 #include "base/base_export.h" | 12 #include "base/base_export.h" |
| 11 #include "base/gtest_prod_util.h" | 13 #include "base/callback.h" |
| 12 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 13 #include "base/timer/timer.h" | |
| 14 #include "base/trace_event/memory_dump_request_args.h" | 15 #include "base/trace_event/memory_dump_request_args.h" |
| 15 | 16 |
| 16 namespace base { | 17 namespace base { |
| 17 class SingleThreadTaskRunner; | 18 class SequencedTaskRunner; |
| 18 | 19 |
| 19 namespace trace_event { | 20 namespace trace_event { |
| 20 | 21 |
| 21 class MemoryDumpManager; | |
| 22 | |
| 23 // Schedules global dump requests based on the triggers added. The methods of | 22 // Schedules global dump requests based on the triggers added. The methods of |
| 24 // this class are NOT thread safe and the client has to take care of invoking | 23 // this class are NOT thread safe and the client has to take care of invoking |
| 25 // all the methods of the class safely. | 24 // all the methods of the class safely. |
| 26 class BASE_EXPORT MemoryDumpScheduler { | 25 class BASE_EXPORT MemoryDumpScheduler { |
| 27 public: | 26 public: |
| 27 using PeriodicCallback = RepeatingCallback<void(MemoryDumpLevelOfDetail)>; |
| 28 |
| 29 // Passed to Start(). |
| 30 struct BASE_EXPORT Config { |
| 31 struct Trigger { |
| 32 MemoryDumpLevelOfDetail level_of_detail; |
| 33 uint32_t period_ms; |
| 34 }; |
| 35 |
| 36 Config(); |
| 37 Config(const Config&); |
| 38 ~Config(); |
| 39 |
| 40 std::vector<Trigger> triggers; |
| 41 PeriodicCallback callback; |
| 42 }; |
| 43 |
| 28 static MemoryDumpScheduler* GetInstance(); | 44 static MemoryDumpScheduler* GetInstance(); |
| 29 | 45 |
| 30 // Initializes the scheduler. NOT thread safe. | 46 void Start(Config, scoped_refptr<SequencedTaskRunner> task_runner); |
| 31 void Setup(MemoryDumpManager* mdm_, | 47 void Stop(); |
| 32 scoped_refptr<SingleThreadTaskRunner> polling_task_runner); | 48 bool is_enabled_for_testing() const { return bool(task_runner_); } |
| 33 | |
| 34 // Adds triggers for scheduling global dumps. Both periodic and peak triggers | |
| 35 // cannot be added together. At the moment the periodic support is limited to | |
| 36 // at most one periodic trigger per dump mode and peak triggers are limited to | |
| 37 // at most one. All intervals should be an integeral multiple of the smallest | |
| 38 // interval specified. NOT thread safe. | |
| 39 void AddTrigger(MemoryDumpType trigger_type, | |
| 40 MemoryDumpLevelOfDetail level_of_detail, | |
| 41 uint32_t min_time_between_dumps_ms); | |
| 42 | |
| 43 // Starts periodic dumps. NOT thread safe and triggers must be added before | |
| 44 // enabling. | |
| 45 void EnablePeriodicTriggerIfNeeded(); | |
| 46 | |
| 47 // Starts polling memory total. NOT thread safe and triggers must be added | |
| 48 // before enabling. | |
| 49 void EnablePollingIfNeeded(); | |
| 50 | |
| 51 // Resets time for triggering dump to account for minimum time between the | |
| 52 // dumps. NOT thread safe. | |
| 53 void NotifyDumpTriggered(); | |
| 54 | |
| 55 // Disables all triggers. NOT thread safe. This should be called before | |
| 56 // polling thread is stopped to stop polling cleanly. | |
| 57 void DisableAllTriggers(); | |
| 58 | 49 |
| 59 private: | 50 private: |
| 60 friend class MemoryDumpManagerTest; | 51 friend class MemoryDumpSchedulerTest; |
| 61 friend class MemoryDumpSchedulerPollingTest; | |
| 62 FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest, TestPollingOnDumpThread); | |
| 63 FRIEND_TEST_ALL_PREFIXES(MemoryDumpSchedulerPollingTest, NotifyDumpTriggered); | |
| 64 | |
| 65 // Helper class to schdule periodic memory dumps. | |
| 66 struct BASE_EXPORT PeriodicTriggerState { | |
| 67 PeriodicTriggerState(); | |
| 68 ~PeriodicTriggerState(); | |
| 69 | |
| 70 bool is_configured; | |
| 71 | |
| 72 RepeatingTimer timer; | |
| 73 uint32_t dump_count; | |
| 74 uint32_t min_timer_period_ms; | |
| 75 uint32_t light_dumps_rate; | |
| 76 uint32_t heavy_dumps_rate; | |
| 77 | |
| 78 uint32_t light_dump_period_ms; | |
| 79 uint32_t heavy_dump_period_ms; | |
| 80 | |
| 81 DISALLOW_COPY_AND_ASSIGN(PeriodicTriggerState); | |
| 82 }; | |
| 83 | |
| 84 struct BASE_EXPORT PollingTriggerState { | |
| 85 enum State { | |
| 86 CONFIGURED, // Polling trigger was added. | |
| 87 ENABLED, // Polling is running. | |
| 88 DISABLED // Polling is disabled. | |
| 89 }; | |
| 90 | |
| 91 static const uint32_t kMaxNumMemorySamples = 50; | |
| 92 | |
| 93 PollingTriggerState(); | |
| 94 ~PollingTriggerState(); | |
| 95 | |
| 96 // Helper to clear the tracked memory totals and poll count from last dump. | |
| 97 void ResetTotals(); | |
| 98 | |
| 99 State current_state; | |
| 100 MemoryDumpLevelOfDetail level_of_detail; | |
| 101 | |
| 102 uint32_t polling_interval_ms; | |
| 103 | |
| 104 // Minimum numer of polls after the last dump at which next dump can be | |
| 105 // triggered. | |
| 106 int min_polls_between_dumps; | |
| 107 int num_polls_from_last_dump; | |
| 108 | |
| 109 uint64_t last_dump_memory_total; | |
| 110 int64_t memory_increase_threshold; | |
| 111 uint64_t last_memory_totals_kb[kMaxNumMemorySamples]; | |
| 112 uint32_t last_memory_totals_kb_index; | |
| 113 | |
| 114 DISALLOW_COPY_AND_ASSIGN(PollingTriggerState); | |
| 115 }; | |
| 116 | |
| 117 MemoryDumpScheduler(); | 52 MemoryDumpScheduler(); |
| 118 ~MemoryDumpScheduler(); | 53 ~MemoryDumpScheduler(); |
| 119 | 54 |
| 120 // Helper to set polling disabled. | 55 void StartInternal(Config); |
| 121 void DisablePollingOnPollingThread(); | 56 void StopInternal(); |
| 57 void Tick(uint32_t expected_generation); |
| 122 | 58 |
| 123 // Periodically called by the timer. | 59 // Accessed only by the public methods (never from the task runner itself). |
| 124 void RequestPeriodicGlobalDump(); | 60 scoped_refptr<SequencedTaskRunner> task_runner_; |
| 125 | 61 |
| 126 // Called for polling memory usage and trigger dumps if peak is detected. | 62 // These fields instead are only accessed from within the task runner. |
| 127 void PollMemoryOnPollingThread(); | 63 uint32_t period_ms_; // 0 == disabled. |
| 128 | 64 uint32_t generation_; // Used to invalidate outstanding tasks after Stop(). |
| 129 // Returns true if peak memory value is detected. | 65 uint32_t tick_count_; |
| 130 bool ShouldTriggerDump(uint64_t current_memory_total); | 66 uint32_t light_dump_rate_; |
| 131 | 67 uint32_t heavy_dump_rate_; |
| 132 // Helper to detect peaks in memory usage. | 68 PeriodicCallback callback_; |
| 133 bool IsCurrentSamplePeak(uint64_t current_memory_total); | |
| 134 | |
| 135 // Must be set before enabling tracing. | |
| 136 static void SetPollingIntervalForTesting(uint32_t interval); | |
| 137 | |
| 138 // True if periodic dumping is enabled. | |
| 139 bool IsPeriodicTimerRunningForTesting(); | |
| 140 | |
| 141 MemoryDumpManager* mdm_; | |
| 142 | |
| 143 // Accessed on the thread of the client before enabling and only accessed on | |
| 144 // the thread that called "EnablePeriodicTriggersIfNeeded()" after enabling. | |
| 145 std::unique_ptr<PeriodicTriggerState> periodic_state_; | |
| 146 | |
| 147 // Accessed on the thread of the client before enabling and only accessed on | |
| 148 // the polling thread after enabling. | |
| 149 std::unique_ptr<PollingTriggerState> polling_state_; | |
| 150 | |
| 151 // Accessed on the thread of the client only. | |
| 152 scoped_refptr<SingleThreadTaskRunner> polling_task_runner_; | |
| 153 | |
| 154 // True when the scheduler is setup. Accessed on the thread of client only. | |
| 155 bool is_setup_; | |
| 156 | 69 |
| 157 DISALLOW_COPY_AND_ASSIGN(MemoryDumpScheduler); | 70 DISALLOW_COPY_AND_ASSIGN(MemoryDumpScheduler); |
| 158 }; | 71 }; |
| 159 | 72 |
| 160 } // namespace trace_event | 73 } // namespace trace_event |
| 161 } // namespace base | 74 } // namespace base |
| 162 | 75 |
| 163 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H | 76 #endif // BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H |
| OLD | NEW |