Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(675)

Side by Side Diff: base/trace_event/memory_dump_scheduler.cc

Issue 2778313002: [memory-infra] Move periodic timer to dump thread
Patch Set: nits. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/trace_event/memory_dump_scheduler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "base/trace_event/memory_dump_scheduler.h" 5 #include "base/trace_event/memory_dump_scheduler.h"
6 6
7 #include "base/process/process_metrics.h" 7 #include "base/process/process_metrics.h"
8 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
9 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
10 #include "base/trace_event/memory_dump_manager.h" 10 #include "base/trace_event/memory_dump_manager.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 12
13 namespace base { 13 namespace base {
14 namespace trace_event { 14 namespace trace_event {
15 15
16 namespace { 16 namespace {
17 // Threshold on increase in memory from last dump beyond which a new dump must 17 // Threshold on increase in memory from last dump beyond which a new dump must
18 // be triggered. 18 // be triggered.
19 int64_t kDefaultMemoryIncreaseThreshold = 50 * 1024 * 1024; // 50MiB 19 int64_t kDefaultMemoryIncreaseThreshold = 50 * 1024 * 1024; // 50MiB
20 const uint32_t kMemoryTotalsPollingInterval = 25; 20 const uint32_t kMemoryTotalsPollingInterval = 25;
21 uint32_t g_polling_interval_ms_for_testing = 0; 21 uint32_t g_polling_interval_ms_for_testing = 0;
22 } // namespace 22 } // namespace
23 23
24 // static 24 // static
25 bool MemoryDumpScheduler::periodic_timer_disabled_for_testing_ = false;
26
27 // static
25 MemoryDumpScheduler* MemoryDumpScheduler::GetInstance() { 28 MemoryDumpScheduler* MemoryDumpScheduler::GetInstance() {
26 static MemoryDumpScheduler* instance = new MemoryDumpScheduler(); 29 static MemoryDumpScheduler* instance = new MemoryDumpScheduler();
27 return instance; 30 return instance;
28 } 31 }
29 32
30 MemoryDumpScheduler::MemoryDumpScheduler() : mdm_(nullptr), is_setup_(false) {} 33 MemoryDumpScheduler::MemoryDumpScheduler() : mdm_(nullptr), is_setup_(false) {}
31 MemoryDumpScheduler::~MemoryDumpScheduler() {} 34 MemoryDumpScheduler::~MemoryDumpScheduler() {}
32 35
33 void MemoryDumpScheduler::Setup( 36 void MemoryDumpScheduler::Setup(
34 MemoryDumpManager* mdm, 37 MemoryDumpManager* mdm,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 84 }
82 85
83 void MemoryDumpScheduler::EnablePeriodicTriggerIfNeeded() { 86 void MemoryDumpScheduler::EnablePeriodicTriggerIfNeeded() {
84 DCHECK(is_setup_); 87 DCHECK(is_setup_);
85 if (!periodic_state_->is_configured || periodic_state_->timer.IsRunning()) 88 if (!periodic_state_->is_configured || periodic_state_->timer.IsRunning())
86 return; 89 return;
87 periodic_state_->light_dumps_rate = periodic_state_->light_dump_period_ms / 90 periodic_state_->light_dumps_rate = periodic_state_->light_dump_period_ms /
88 periodic_state_->min_timer_period_ms; 91 periodic_state_->min_timer_period_ms;
89 periodic_state_->heavy_dumps_rate = periodic_state_->heavy_dump_period_ms / 92 periodic_state_->heavy_dumps_rate = periodic_state_->heavy_dump_period_ms /
90 periodic_state_->min_timer_period_ms; 93 periodic_state_->min_timer_period_ms;
94 periodic_state_->dump_count = 0;
95 periodic_state_->is_enabled_for_testing = true;
91 96
92 periodic_state_->dump_count = 0; 97 if (periodic_timer_disabled_for_testing_)
98 return;
99 polling_task_runner_->PostTask(
100 FROM_HERE, Bind(&MemoryDumpScheduler::EnablePeriodicTimerOnPollingThread,
101 Unretained(this)));
102 }
103
104 void MemoryDumpScheduler::EnablePeriodicTimerOnPollingThread() {
93 periodic_state_->timer.Start( 105 periodic_state_->timer.Start(
94 FROM_HERE, 106 FROM_HERE,
95 TimeDelta::FromMilliseconds(periodic_state_->min_timer_period_ms), 107 TimeDelta::FromMilliseconds(periodic_state_->min_timer_period_ms),
96 Bind(&MemoryDumpScheduler::RequestPeriodicGlobalDump, Unretained(this))); 108 Bind(&MemoryDumpScheduler::RequestPeriodicGlobalDump, Unretained(this)));
97 } 109 }
98 110
99 void MemoryDumpScheduler::EnablePollingIfNeeded() { 111 void MemoryDumpScheduler::EnablePollingIfNeeded() {
100 DCHECK(is_setup_); 112 DCHECK(is_setup_);
101 if (polling_state_->current_state != PollingTriggerState::CONFIGURED) 113 if (polling_state_->current_state != PollingTriggerState::CONFIGURED)
102 return; 114 return;
(...skipping 17 matching lines...) Expand all
120 132
121 if (!polling_state_ || 133 if (!polling_state_ ||
122 polling_state_->current_state != PollingTriggerState::ENABLED) { 134 polling_state_->current_state != PollingTriggerState::ENABLED) {
123 return; 135 return;
124 } 136 }
125 137
126 polling_state_->ResetTotals(); 138 polling_state_->ResetTotals();
127 } 139 }
128 140
129 void MemoryDumpScheduler::DisableAllTriggers() { 141 void MemoryDumpScheduler::DisableAllTriggers() {
142 if (polling_task_runner_) {
143 polling_task_runner_->PostTask(
144 FROM_HERE, Bind(&MemoryDumpScheduler::DisableTriggersOnPollingThread,
145 Unretained(this)));
146 polling_task_runner_ = nullptr;
147 }
148 is_setup_ = false;
149 }
150
151 void MemoryDumpScheduler::DisableTriggersOnPollingThread() {
130 if (periodic_state_) { 152 if (periodic_state_) {
131 if (periodic_state_->timer.IsRunning()) 153 if (periodic_state_->timer.IsRunning())
132 periodic_state_->timer.Stop(); 154 periodic_state_->timer.Stop();
133 periodic_state_.reset(); 155 periodic_state_.reset();
134 } 156 }
135 157
136 if (polling_task_runner_) {
137 DCHECK(polling_state_);
138 polling_task_runner_->PostTask(
139 FROM_HERE, Bind(&MemoryDumpScheduler::DisablePollingOnPollingThread,
140 Unretained(this)));
141 polling_task_runner_ = nullptr;
142 }
143 is_setup_ = false;
144 }
145
146 void MemoryDumpScheduler::DisablePollingOnPollingThread() {
147 polling_state_->current_state = PollingTriggerState::DISABLED; 158 polling_state_->current_state = PollingTriggerState::DISABLED;
148 polling_state_.reset(); 159 polling_state_.reset();
149 } 160 }
150 161
151 // static 162 // static
152 void MemoryDumpScheduler::SetPollingIntervalForTesting(uint32_t interval) { 163 void MemoryDumpScheduler::SetPollingIntervalForTesting(uint32_t interval) {
153 g_polling_interval_ms_for_testing = interval; 164 g_polling_interval_ms_for_testing = interval;
154 } 165 }
155 166
167 void MemoryDumpScheduler::DisablePeriodicTimerForTesting(bool disable) {
168 periodic_timer_disabled_for_testing_ = disable;
169 }
170
156 bool MemoryDumpScheduler::IsPeriodicTimerRunningForTesting() { 171 bool MemoryDumpScheduler::IsPeriodicTimerRunningForTesting() {
157 return periodic_state_->timer.IsRunning(); 172 return periodic_state_->is_enabled_for_testing;
158 } 173 }
159 174
160 void MemoryDumpScheduler::RequestPeriodicGlobalDump() { 175 void MemoryDumpScheduler::RequestPeriodicGlobalDump() {
176 // In case it's called after timer stopped.
177 if (!periodic_state_)
178 return;
179
161 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; 180 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND;
162 if (periodic_state_->light_dumps_rate > 0 && 181 if (periodic_state_->light_dumps_rate > 0 &&
163 periodic_state_->dump_count % periodic_state_->light_dumps_rate == 0) 182 periodic_state_->dump_count % periodic_state_->light_dumps_rate == 0)
164 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; 183 level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
165 if (periodic_state_->heavy_dumps_rate > 0 && 184 if (periodic_state_->heavy_dumps_rate > 0 &&
166 periodic_state_->dump_count % periodic_state_->heavy_dumps_rate == 0) 185 periodic_state_->dump_count % periodic_state_->heavy_dumps_rate == 0)
167 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; 186 level_of_detail = MemoryDumpLevelOfDetail::DETAILED;
168 ++periodic_state_->dump_count; 187 ++periodic_state_->dump_count;
169 188
170 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); 189 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
171 } 190 }
172 191
173 void MemoryDumpScheduler::PollMemoryOnPollingThread() { 192 void MemoryDumpScheduler::PollMemoryOnPollingThread() {
174 if (polling_state_->current_state != PollingTriggerState::ENABLED) 193 if (!polling_state_)
175 return; 194 return;
176 195
177 uint64_t polled_memory = 0; 196 uint64_t polled_memory = 0;
178 bool res = mdm_->PollFastMemoryTotal(&polled_memory); 197 bool res = mdm_->PollFastMemoryTotal(&polled_memory);
179 DCHECK(res); 198 DCHECK(res);
180 if (polling_state_->level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { 199 if (polling_state_->level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
181 TRACE_COUNTER1(MemoryDumpManager::kTraceCategory, "PolledMemoryMB", 200 TRACE_COUNTER1(MemoryDumpManager::kTraceCategory, "PolledMemoryMB",
182 polled_memory / 1024 / 1024); 201 polled_memory / 1024 / 1024);
183 } 202 }
184 203
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 (3.69 * 3.69 * variance); 285 (3.69 * 3.69 * variance);
267 } 286 }
268 287
269 MemoryDumpScheduler::PeriodicTriggerState::PeriodicTriggerState() 288 MemoryDumpScheduler::PeriodicTriggerState::PeriodicTriggerState()
270 : is_configured(false), 289 : is_configured(false),
271 dump_count(0), 290 dump_count(0),
272 min_timer_period_ms(std::numeric_limits<uint32_t>::max()), 291 min_timer_period_ms(std::numeric_limits<uint32_t>::max()),
273 light_dumps_rate(0), 292 light_dumps_rate(0),
274 heavy_dumps_rate(0), 293 heavy_dumps_rate(0),
275 light_dump_period_ms(0), 294 light_dump_period_ms(0),
276 heavy_dump_period_ms(0) {} 295 heavy_dump_period_ms(0),
296 is_enabled_for_testing(false) {}
277 297
278 MemoryDumpScheduler::PeriodicTriggerState::~PeriodicTriggerState() { 298 MemoryDumpScheduler::PeriodicTriggerState::~PeriodicTriggerState() {
279 DCHECK(!timer.IsRunning()); 299 DCHECK(!timer.IsRunning());
280 } 300 }
281 301
282 MemoryDumpScheduler::PollingTriggerState::PollingTriggerState() 302 MemoryDumpScheduler::PollingTriggerState::PollingTriggerState()
283 : current_state(DISABLED), 303 : current_state(DISABLED),
284 level_of_detail(MemoryDumpLevelOfDetail::FIRST), 304 level_of_detail(MemoryDumpLevelOfDetail::FIRST),
285 polling_interval_ms(g_polling_interval_ms_for_testing 305 polling_interval_ms(g_polling_interval_ms_for_testing
286 ? g_polling_interval_ms_for_testing 306 ? g_polling_interval_ms_for_testing
(...skipping 30 matching lines...) Expand all
317 last_memory_totals_kb[last_memory_totals_kb_index] * 1024; 337 last_memory_totals_kb[last_memory_totals_kb_index] * 1024;
318 } 338 }
319 num_polls_from_last_dump = 0; 339 num_polls_from_last_dump = 0;
320 for (uint32_t i = 0; i < kMaxNumMemorySamples; ++i) 340 for (uint32_t i = 0; i < kMaxNumMemorySamples; ++i)
321 last_memory_totals_kb[i] = 0; 341 last_memory_totals_kb[i] = 0;
322 last_memory_totals_kb_index = 0; 342 last_memory_totals_kb_index = 0;
323 } 343 }
324 344
325 } // namespace trace_event 345 } // namespace trace_event
326 } // namespace base 346 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/memory_dump_scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698