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

Side by Side Diff: base/metrics/statistics_recorder.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 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/metrics/statistics_recorder.h ('k') | base/metrics/statistics_recorder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/metrics/statistics_recorder.h" 5 #include "base/metrics/statistics_recorder.h"
6 6
7 #include "base/at_exit.h" 7 #include "base/at_exit.h"
8 #include "base/debug/leak_annotations.h" 8 #include "base/debug/leak_annotations.h"
9 #include "base/json/string_escape.h" 9 #include "base/json/string_escape.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h"
13 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
14 #include "base/synchronization/lock.h" 15 #include "base/synchronization/lock.h"
15 #include "base/values.h" 16 #include "base/values.h"
16 17
17 namespace { 18 namespace {
18 // Initialize histogram statistics gathering system. 19 // Initialize histogram statistics gathering system.
19 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ = 20 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ =
20 LAZY_INSTANCE_INITIALIZER; 21 LAZY_INSTANCE_INITIALIZER;
21 } // namespace 22 } // namespace
22 23
(...skipping 27 matching lines...) Expand all
50 } 51 }
51 52
52 HistogramBase* histogram_to_delete = NULL; 53 HistogramBase* histogram_to_delete = NULL;
53 HistogramBase* histogram_to_return = NULL; 54 HistogramBase* histogram_to_return = NULL;
54 { 55 {
55 base::AutoLock auto_lock(*lock_); 56 base::AutoLock auto_lock(*lock_);
56 if (histograms_ == NULL) { 57 if (histograms_ == NULL) {
57 histogram_to_return = histogram; 58 histogram_to_return = histogram;
58 } else { 59 } else {
59 const std::string& name = histogram->histogram_name(); 60 const std::string& name = histogram->histogram_name();
60 HistogramMap::iterator it = histograms_->find(name); 61 HistogramMap::iterator it = histograms_->find(HistogramNameRef(name));
61 if (histograms_->end() == it) { 62 if (histograms_->end() == it) {
62 (*histograms_)[name] = histogram; 63 (*histograms_)[HistogramNameRef(name)] = histogram;
63 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 64 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
65 // If there are callbacks for this histogram, we set the kCallbackExists
66 // flag.
67 auto callback_iterator = callbacks_->find(name);
68 if (callback_iterator != callbacks_->end()) {
69 if (!callback_iterator->second.is_null())
70 histogram->SetFlags(HistogramBase::kCallbackExists);
71 else
72 histogram->ClearFlags(HistogramBase::kCallbackExists);
73 }
64 histogram_to_return = histogram; 74 histogram_to_return = histogram;
65 } else if (histogram == it->second) { 75 } else if (histogram == it->second) {
66 // The histogram was registered before. 76 // The histogram was registered before.
67 histogram_to_return = histogram; 77 histogram_to_return = histogram;
68 } else { 78 } else {
69 // We already have one histogram with this name. 79 // We already have one histogram with this name.
70 histogram_to_return = it->second; 80 histogram_to_return = it->second;
71 histogram_to_delete = histogram; 81 histogram_to_delete = histogram;
72 } 82 }
73 } 83 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 193
184 // static 194 // static
185 void StatisticsRecorder::GetHistograms(Histograms* output) { 195 void StatisticsRecorder::GetHistograms(Histograms* output) {
186 if (lock_ == NULL) 196 if (lock_ == NULL)
187 return; 197 return;
188 base::AutoLock auto_lock(*lock_); 198 base::AutoLock auto_lock(*lock_);
189 if (histograms_ == NULL) 199 if (histograms_ == NULL)
190 return; 200 return;
191 201
192 for (const auto& entry : *histograms_) { 202 for (const auto& entry : *histograms_) {
193 DCHECK_EQ(entry.first, entry.second->histogram_name()); 203 DCHECK_EQ(entry.first.name_, entry.second->histogram_name());
194 output->push_back(entry.second); 204 output->push_back(entry.second);
195 } 205 }
196 } 206 }
197 207
198 // static 208 // static
199 void StatisticsRecorder::GetBucketRanges( 209 void StatisticsRecorder::GetBucketRanges(
200 std::vector<const BucketRanges*>* output) { 210 std::vector<const BucketRanges*>* output) {
201 if (lock_ == NULL) 211 if (lock_ == NULL)
202 return; 212 return;
203 base::AutoLock auto_lock(*lock_); 213 base::AutoLock auto_lock(*lock_);
204 if (ranges_ == NULL) 214 if (ranges_ == NULL)
205 return; 215 return;
206 216
207 for (const auto& entry : *ranges_) { 217 for (const auto& entry : *ranges_) {
208 for (const auto& range_entry : *entry.second) { 218 for (const auto& range_entry : *entry.second) {
209 output->push_back(range_entry); 219 output->push_back(range_entry);
210 } 220 }
211 } 221 }
212 } 222 }
213 223
214 // static 224 // static
215 HistogramBase* StatisticsRecorder::FindHistogram(const std::string& name) { 225 HistogramBase* StatisticsRecorder::FindHistogram(const std::string& name) {
216 if (lock_ == NULL) 226 if (lock_ == NULL)
217 return NULL; 227 return NULL;
218 base::AutoLock auto_lock(*lock_); 228 base::AutoLock auto_lock(*lock_);
219 if (histograms_ == NULL) 229 if (histograms_ == NULL)
220 return NULL; 230 return NULL;
221 231
222 HistogramMap::iterator it = histograms_->find(name); 232 HistogramMap::iterator it = histograms_->find(HistogramNameRef(name));
223 if (histograms_->end() == it) 233 if (histograms_->end() == it)
224 return NULL; 234 return NULL;
225 return it->second; 235 return it->second;
226 } 236 }
227 237
238 // static
239 bool StatisticsRecorder::SetCallback(
240 const std::string& name,
241 const StatisticsRecorder::OnSampleCallback& cb) {
242 DCHECK(!cb.is_null());
243 if (lock_ == NULL)
244 return false;
245 base::AutoLock auto_lock(*lock_);
246 if (histograms_ == NULL)
247 return false;
248
249 if (ContainsKey(*callbacks_, name))
250 return false;
251 callbacks_->insert(std::make_pair(name, cb));
252
253 auto histogram_iterator = histograms_->find(HistogramNameRef(name));
254 if (histogram_iterator != histograms_->end())
255 histogram_iterator->second->SetFlags(HistogramBase::kCallbackExists);
256
257 return true;
258 }
259
260 // static
261 void StatisticsRecorder::ClearCallback(const std::string& name) {
262 if (lock_ == NULL)
263 return;
264 base::AutoLock auto_lock(*lock_);
265 if (histograms_ == NULL)
266 return;
267
268 callbacks_->erase(name);
269
270 // We also clear the flag from the histogram (if it exists).
271 auto histogram_iterator = histograms_->find(HistogramNameRef(name));
272 if (histogram_iterator != histograms_->end())
273 histogram_iterator->second->ClearFlags(HistogramBase::kCallbackExists);
274 }
275
276 // static
277 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
278 const std::string& name) {
279 if (lock_ == NULL)
280 return OnSampleCallback();
281 base::AutoLock auto_lock(*lock_);
282 if (histograms_ == NULL)
283 return OnSampleCallback();
284
285 auto callback_iterator = callbacks_->find(name);
286 return callback_iterator != callbacks_->end() ? callback_iterator->second
287 : OnSampleCallback();
288 }
289
228 // private static 290 // private static
229 void StatisticsRecorder::GetSnapshot(const std::string& query, 291 void StatisticsRecorder::GetSnapshot(const std::string& query,
230 Histograms* snapshot) { 292 Histograms* snapshot) {
231 if (lock_ == NULL) 293 if (lock_ == NULL)
232 return; 294 return;
233 base::AutoLock auto_lock(*lock_); 295 base::AutoLock auto_lock(*lock_);
234 if (histograms_ == NULL) 296 if (histograms_ == NULL)
235 return; 297 return;
236 298
237 for (const auto& entry : *histograms_) { 299 for (const auto& entry : *histograms_) {
238 if (entry.first.find(query) != std::string::npos) 300 if (entry.first.name_.find(query) != std::string::npos)
239 snapshot->push_back(entry.second); 301 snapshot->push_back(entry.second);
240 } 302 }
241 } 303 }
242 304
243 // This singleton instance should be started during the single threaded portion 305 // This singleton instance should be started during the single threaded portion
244 // of main(), and hence it is not thread safe. It initializes globals to 306 // of main(), and hence it is not thread safe. It initializes globals to
245 // provide support for all future calls. 307 // provide support for all future calls.
246 StatisticsRecorder::StatisticsRecorder() { 308 StatisticsRecorder::StatisticsRecorder() {
247 DCHECK(!histograms_); 309 DCHECK(!histograms_);
248 if (lock_ == NULL) { 310 if (lock_ == NULL) {
249 // This will leak on purpose. It's the only way to make sure we won't race 311 // This will leak on purpose. It's the only way to make sure we won't race
250 // against the static uninitialization of the module while one of our 312 // against the static uninitialization of the module while one of our
251 // static methods relying on the lock get called at an inappropriate time 313 // static methods relying on the lock get called at an inappropriate time
252 // during the termination phase. Since it's a static data member, we will 314 // during the termination phase. Since it's a static data member, we will
253 // leak one per process, which would be similar to the instance allocated 315 // leak one per process, which would be similar to the instance allocated
254 // during static initialization and released only on process termination. 316 // during static initialization and released only on process termination.
255 lock_ = new base::Lock; 317 lock_ = new base::Lock;
256 } 318 }
257 base::AutoLock auto_lock(*lock_); 319 base::AutoLock auto_lock(*lock_);
258 histograms_ = new HistogramMap; 320 histograms_ = new HistogramMap;
321 callbacks_ = new CallbackMap;
259 ranges_ = new RangesMap; 322 ranges_ = new RangesMap;
260 323
261 if (VLOG_IS_ON(1)) 324 if (VLOG_IS_ON(1))
262 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); 325 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this);
263 } 326 }
264 327
265 // static 328 // static
266 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) { 329 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) {
267 std::string output; 330 std::string output;
268 StatisticsRecorder::WriteGraph(std::string(), &output); 331 StatisticsRecorder::WriteGraph(std::string(), &output);
269 VLOG(1) << output; 332 VLOG(1) << output;
270 } 333 }
271 334
272 StatisticsRecorder::~StatisticsRecorder() { 335 StatisticsRecorder::~StatisticsRecorder() {
273 DCHECK(histograms_ && ranges_ && lock_); 336 DCHECK(histograms_ && ranges_ && lock_);
274 337
275 // Clean up. 338 // Clean up.
276 scoped_ptr<HistogramMap> histograms_deleter; 339 scoped_ptr<HistogramMap> histograms_deleter;
340 scoped_ptr<CallbackMap> callbacks_deleter;
277 scoped_ptr<RangesMap> ranges_deleter; 341 scoped_ptr<RangesMap> ranges_deleter;
278 // We don't delete lock_ on purpose to avoid having to properly protect 342 // We don't delete lock_ on purpose to avoid having to properly protect
279 // against it going away after we checked for NULL in the static methods. 343 // against it going away after we checked for NULL in the static methods.
280 { 344 {
281 base::AutoLock auto_lock(*lock_); 345 base::AutoLock auto_lock(*lock_);
282 histograms_deleter.reset(histograms_); 346 histograms_deleter.reset(histograms_);
347 callbacks_deleter.reset(callbacks_);
283 ranges_deleter.reset(ranges_); 348 ranges_deleter.reset(ranges_);
284 histograms_ = NULL; 349 histograms_ = NULL;
350 callbacks_ = NULL;
285 ranges_ = NULL; 351 ranges_ = NULL;
286 } 352 }
287 // We are going to leak the histograms and the ranges. 353 // We are going to leak the histograms and the ranges.
288 } 354 }
289 355
290 356
291 // static 357 // static
292 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 358 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
293 // static 359 // static
360 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
361 // static
294 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; 362 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
295 // static 363 // static
296 base::Lock* StatisticsRecorder::lock_ = NULL; 364 base::Lock* StatisticsRecorder::lock_ = NULL;
297 365
298 } // namespace base 366 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/statistics_recorder.h ('k') | base/metrics/statistics_recorder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698