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

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

Issue 2786373002: memory-infra: Add peak-detector skeleton. (Closed)
Patch Set: rebase + introduce teardown + reset instance in test 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/trace_event/memory_peak_detector.h"
6
7 #include <stdint.h>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/threading/sequenced_task_runner_handle.h"
12 #include "base/time/time.h"
13 #include "base/trace_event/memory_dump_provider_info.h"
14
15 namespace base {
16 namespace trace_event {
17
18 // static
19 MemoryPeakDetector* MemoryPeakDetector::GetInstance() {
20 static MemoryPeakDetector* instance = new MemoryPeakDetector();
21 return instance;
22 }
23
24 MemoryPeakDetector::MemoryPeakDetector()
25 : state_(NOT_INITIALIZED),
26 polling_interval_ms_(0),
27 poll_tasks_count_for_testing_(0) {}
28
29 MemoryPeakDetector::~MemoryPeakDetector() {
30 // This should be hit only in tests, in which case the test is expected to
31 // TearDown() cleanly and not leave the peak detector running.
32 DCHECK_EQ(NOT_INITIALIZED, state_);
33 }
34
35 void MemoryPeakDetector::Setup(
36 const GetDumpProvidersFunction& get_dump_providers_function,
37 const scoped_refptr<SequencedTaskRunner>& task_runner,
38 const OnPeakDetectedCallback& on_peak_detected_callback) {
39 DCHECK(!get_dump_providers_function.is_null());
40 DCHECK(task_runner);
41 DCHECK(!on_peak_detected_callback.is_null());
42 DCHECK(state_ == NOT_INITIALIZED || state_ == DISABLED);
43 DCHECK(dump_providers_.empty());
44 get_dump_providers_function_ = get_dump_providers_function;
45 task_runner_ = task_runner;
46 on_peak_detected_callback_ = on_peak_detected_callback;
47 state_ = DISABLED;
48 }
49
50 void MemoryPeakDetector::TearDown() {
51 if (task_runner_) {
52 task_runner_->PostTask(
53 FROM_HERE,
54 Bind(&MemoryPeakDetector::TearDownInternal, Unretained(this)));
55 }
56 task_runner_ = nullptr;
57 }
58
59 void MemoryPeakDetector::Start() {
60 task_runner_->PostTask(
61 FROM_HERE, Bind(&MemoryPeakDetector::StartInternal, Unretained(this)));
62 }
63
64 void MemoryPeakDetector::Stop() {
65 task_runner_->PostTask(
66 FROM_HERE, Bind(&MemoryPeakDetector::StopInternal, Unretained(this)));
67 }
68
69 void MemoryPeakDetector::NotifyMemoryDumpProvidersChanged() {
70 // It is possible to call this before the first Initialize() call, in which
71 // case we want to just make this a noop. Start() will fetch the MDP list
72 // anyways later.
73 if (!task_runner_)
74 return;
75 task_runner_->PostTask(
76 FROM_HERE,
77 Bind(&MemoryPeakDetector::ReloadDumpProvidersAndStartPollingIfNeeded,
78 Unretained(this)));
79 }
80
81 void MemoryPeakDetector::StartInternal() {
82 DCHECK_EQ(DISABLED, state_);
83 state_ = ENABLED;
84 polling_interval_ms_ = 1; // TODO(primiano): temporary until next CL.
85
86 // If there are any dump providers available, NotifyMemoryDumpProvidersChanged
87 // will fetch them and start the polling. Otherwise this will remain in the
88 // ENABLED state and the actual polling will start on the next call to
89 // ReloadDumpProvidersAndStartPollingIfNeeded().
90 // Depending on the sandbox model, it is possible that no polling-capable dump
91 // providers will be ever available.
92 ReloadDumpProvidersAndStartPollingIfNeeded();
93 }
94
95 void MemoryPeakDetector::StopInternal() {
96 DCHECK_NE(NOT_INITIALIZED, state_);
97 state_ = DISABLED;
98 dump_providers_.clear();
99 }
100
101 void MemoryPeakDetector::TearDownInternal() {
102 StopInternal();
103 get_dump_providers_function_.Reset();
104 on_peak_detected_callback_.Reset();
105 state_ = NOT_INITIALIZED;
106 }
107
108 void MemoryPeakDetector::ReloadDumpProvidersAndStartPollingIfNeeded() {
109 if (state_ == DISABLED || state_ == NOT_INITIALIZED)
110 return; // Start() will re-fetch the MDP list later.
111
112 DCHECK((state_ == RUNNING && !dump_providers_.empty()) ||
113 (state_ == ENABLED && dump_providers_.empty()));
114
115 dump_providers_.clear();
116
117 // This is really MemoryDumpManager::GetDumpProvidersForPolling, % testing.
118 get_dump_providers_function_.Run(&dump_providers_);
119
120 if (state_ == ENABLED && !dump_providers_.empty()) {
121 // It's now time to start polling for realz.
122 state_ = RUNNING;
123 task_runner_->PostTask(
124 FROM_HERE,
125 Bind(&MemoryPeakDetector::PollMemoryAndDetectPeak, Unretained(this)));
126 } else if (state_ == RUNNING && dump_providers_.empty()) {
127 // Will cause the next PollMemoryAndDetectPeak() task to early return.
128 state_ = ENABLED;
129 }
130 }
131
132 void MemoryPeakDetector::PollMemoryAndDetectPeak() {
133 if (state_ != RUNNING)
134 return;
135
136 // We should never end up in a situation where state_ == RUNNING but all dump
137 // providers are gone.
138 DCHECK(!dump_providers_.empty());
139
140 poll_tasks_count_for_testing_++;
141 uint64_t memory_total = 0;
142 for (const scoped_refptr<MemoryDumpProviderInfo>& mdp_info :
143 dump_providers_) {
144 DCHECK(mdp_info->options.is_fast_polling_supported);
145 uint64_t value = 0;
146 mdp_info->dump_provider->PollFastMemoryTotal(&value);
147 memory_total += value;
148 }
149 ignore_result(memory_total); // TODO(primiano): temporary until next CL.
150
151 // TODO(primiano): Move actual peak detection logic from the
152 // MemoryDumpScheduler in next CLs.
153
154 SequencedTaskRunnerHandle::Get()->PostDelayedTask(
155 FROM_HERE,
156 Bind(&MemoryPeakDetector::PollMemoryAndDetectPeak, Unretained(this)),
157 TimeDelta::FromMilliseconds(polling_interval_ms_));
158 }
159
160 } // namespace trace_event
161 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698