OLD | NEW |
---|---|
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 <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 StatisticsRecorder::~StatisticsRecorder() { | 80 StatisticsRecorder::~StatisticsRecorder() { |
81 DCHECK(histograms_); | 81 DCHECK(histograms_); |
82 DCHECK(ranges_); | 82 DCHECK(ranges_); |
83 | 83 |
84 // Clean out what this object created and then restore what existed before. | 84 // Clean out what this object created and then restore what existed before. |
85 Reset(); | 85 Reset(); |
86 base::AutoLock auto_lock(lock_.Get()); | 86 base::AutoLock auto_lock(lock_.Get()); |
87 histograms_ = existing_histograms_.release(); | 87 histograms_ = existing_histograms_.release(); |
88 callbacks_ = existing_callbacks_.release(); | 88 callbacks_ = existing_callbacks_.release(); |
89 ranges_ = existing_ranges_.release(); | 89 ranges_ = existing_ranges_.release(); |
90 providers_ = existing_providers_.release(); | |
90 } | 91 } |
91 | 92 |
92 // static | 93 // static |
93 void StatisticsRecorder::Initialize() { | 94 void StatisticsRecorder::Initialize() { |
94 // Tests sometimes create local StatisticsRecorders in order to provide a | 95 // Tests sometimes create local StatisticsRecorders in order to provide a |
95 // contained environment of histograms that can be later discarded. If a | 96 // contained environment of histograms that can be later discarded. If a |
96 // true global instance gets created in this environment then it will | 97 // true global instance gets created in this environment then it will |
97 // eventually get disconnected when the local instance destructs and | 98 // eventually get disconnected when the local instance destructs and |
98 // restores the previous state, resulting in no StatisticsRecorder at all. | 99 // restores the previous state, resulting in no StatisticsRecorder at all. |
99 // The global lazy instance, however, will remain valid thus ensuring that | 100 // The global lazy instance, however, will remain valid thus ensuring that |
100 // another never gets installed via this method. If a |histograms_| map | 101 // another never gets installed via this method. If a |histograms_| map |
101 // exists then assume the StatisticsRecorder is already "initialized". | 102 // exists then assume the StatisticsRecorder is already "initialized". |
102 if (histograms_) | 103 if (histograms_) |
103 return; | 104 return; |
104 | 105 |
105 // Ensure that an instance of the StatisticsRecorder object is created. | 106 // Ensure that an instance of the StatisticsRecorder object is created. |
106 g_statistics_recorder_.Get(); | 107 g_statistics_recorder_.Get(); |
107 } | 108 } |
108 | 109 |
109 // static | 110 // static |
110 bool StatisticsRecorder::IsActive() { | 111 bool StatisticsRecorder::IsActive() { |
111 base::AutoLock auto_lock(lock_.Get()); | 112 base::AutoLock auto_lock(lock_.Get()); |
112 return histograms_ != nullptr; | 113 return histograms_ != nullptr; |
113 } | 114 } |
114 | 115 |
115 // static | 116 // static |
117 void StatisticsRecorder::RegisterHistogramProvider( | |
118 const WeakPtr<HistogramProvider>& provider) { | |
119 providers_->push_back(provider); | |
120 } | |
121 | |
122 // static | |
116 HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate( | 123 HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate( |
117 HistogramBase* histogram) { | 124 HistogramBase* histogram) { |
118 HistogramBase* histogram_to_delete = nullptr; | 125 HistogramBase* histogram_to_delete = nullptr; |
119 HistogramBase* histogram_to_return = nullptr; | 126 HistogramBase* histogram_to_return = nullptr; |
120 { | 127 { |
121 base::AutoLock auto_lock(lock_.Get()); | 128 base::AutoLock auto_lock(lock_.Get()); |
122 if (!histograms_) { | 129 if (!histograms_) { |
123 histogram_to_return = histogram; | 130 histogram_to_return = histogram; |
124 | 131 |
125 // As per crbug.com/79322 the histograms are intentionally leaked, so we | 132 // As per crbug.com/79322 the histograms are intentionally leaked, so we |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 if (!histograms_) | 307 if (!histograms_) |
301 return nullptr; | 308 return nullptr; |
302 | 309 |
303 HistogramMap::iterator it = histograms_->find(name); | 310 HistogramMap::iterator it = histograms_->find(name); |
304 if (histograms_->end() == it) | 311 if (histograms_->end() == it) |
305 return nullptr; | 312 return nullptr; |
306 return it->second; | 313 return it->second; |
307 } | 314 } |
308 | 315 |
309 // static | 316 // static |
317 void StatisticsRecorder::ImportProvidedHistograms() { | |
Alexei Svitkine (slow)
2017/01/27 16:22:03
Can you add a thread check here?
bcwhite
2017/01/27 18:05:31
Not sure if I can because base/ doesn't generally
Alexei Svitkine (slow)
2017/01/27 18:06:57
Can you add base::ThreadChecker as a member and us
bcwhite
2017/01/27 18:12:57
These are static methods so there's no object to h
| |
318 if (!providers_) | |
319 return; | |
320 | |
321 // Merge histogram data from each provider in turn. | |
322 for (const WeakPtr<HistogramProvider>& provider : *providers_) { | |
323 if (provider) | |
Alexei Svitkine (slow)
2017/01/27 16:22:03
Nit: Maybe add a comment here to mention this is c
bcwhite
2017/01/27 18:05:31
Done.
| |
324 provider->MergeHistogramDeltas(); | |
325 } | |
326 } | |
327 | |
328 // static | |
310 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin( | 329 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin( |
311 bool include_persistent) { | 330 bool include_persistent) { |
312 DCHECK(histograms_); | 331 DCHECK(histograms_); |
313 ImportGlobalPersistentHistograms(); | 332 ImportGlobalPersistentHistograms(); |
314 | 333 |
315 HistogramMap::iterator iter_begin; | 334 HistogramMap::iterator iter_begin; |
316 { | 335 { |
317 base::AutoLock auto_lock(lock_.Get()); | 336 base::AutoLock auto_lock(lock_.Get()); |
318 iter_begin = histograms_->begin(); | 337 iter_begin = histograms_->begin(); |
319 } | 338 } |
(...skipping 19 matching lines...) Expand all Loading... | |
339 g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock(); | 358 g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock(); |
340 } | 359 } |
341 | 360 |
342 // static | 361 // static |
343 void StatisticsRecorder::GetSnapshot(const std::string& query, | 362 void StatisticsRecorder::GetSnapshot(const std::string& query, |
344 Histograms* snapshot) { | 363 Histograms* snapshot) { |
345 base::AutoLock auto_lock(lock_.Get()); | 364 base::AutoLock auto_lock(lock_.Get()); |
346 if (!histograms_) | 365 if (!histograms_) |
347 return; | 366 return; |
348 | 367 |
368 ImportGlobalPersistentHistograms(); | |
369 | |
349 for (const auto& entry : *histograms_) { | 370 for (const auto& entry : *histograms_) { |
350 if (entry.second->histogram_name().find(query) != std::string::npos) | 371 if (entry.second->histogram_name().find(query) != std::string::npos) |
351 snapshot->push_back(entry.second); | 372 snapshot->push_back(entry.second); |
352 } | 373 } |
353 } | 374 } |
354 | 375 |
355 // static | 376 // static |
356 bool StatisticsRecorder::SetCallback( | 377 bool StatisticsRecorder::SetCallback( |
357 const std::string& name, | 378 const std::string& name, |
358 const StatisticsRecorder::OnSampleCallback& cb) { | 379 const StatisticsRecorder::OnSampleCallback& cb) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 | 472 |
452 // This singleton instance should be started during the single threaded portion | 473 // This singleton instance should be started during the single threaded portion |
453 // of main(), and hence it is not thread safe. It initializes globals to | 474 // of main(), and hence it is not thread safe. It initializes globals to |
454 // provide support for all future calls. | 475 // provide support for all future calls. |
455 StatisticsRecorder::StatisticsRecorder() { | 476 StatisticsRecorder::StatisticsRecorder() { |
456 base::AutoLock auto_lock(lock_.Get()); | 477 base::AutoLock auto_lock(lock_.Get()); |
457 | 478 |
458 existing_histograms_.reset(histograms_); | 479 existing_histograms_.reset(histograms_); |
459 existing_callbacks_.reset(callbacks_); | 480 existing_callbacks_.reset(callbacks_); |
460 existing_ranges_.reset(ranges_); | 481 existing_ranges_.reset(ranges_); |
482 existing_providers_.reset(providers_); | |
461 | 483 |
462 histograms_ = new HistogramMap; | 484 histograms_ = new HistogramMap; |
463 callbacks_ = new CallbackMap; | 485 callbacks_ = new CallbackMap; |
464 ranges_ = new RangesMap; | 486 ranges_ = new RangesMap; |
487 providers_ = new HistogramProviders; | |
465 | 488 |
466 InitLogOnShutdownWithoutLock(); | 489 InitLogOnShutdownWithoutLock(); |
467 } | 490 } |
468 | 491 |
469 void StatisticsRecorder::InitLogOnShutdownWithoutLock() { | 492 void StatisticsRecorder::InitLogOnShutdownWithoutLock() { |
470 if (!vlog_initialized_ && VLOG_IS_ON(1)) { | 493 if (!vlog_initialized_ && VLOG_IS_ON(1)) { |
471 vlog_initialized_ = true; | 494 vlog_initialized_ = true; |
472 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); | 495 AtExitManager::RegisterCallback(&DumpHistogramsToVlog, this); |
473 } | 496 } |
474 } | 497 } |
475 | 498 |
476 // static | 499 // static |
477 void StatisticsRecorder::Reset() { | 500 void StatisticsRecorder::Reset() { |
478 | 501 |
479 std::unique_ptr<HistogramMap> histograms_deleter; | 502 std::unique_ptr<HistogramMap> histograms_deleter; |
480 std::unique_ptr<CallbackMap> callbacks_deleter; | 503 std::unique_ptr<CallbackMap> callbacks_deleter; |
481 std::unique_ptr<RangesMap> ranges_deleter; | 504 std::unique_ptr<RangesMap> ranges_deleter; |
505 std::unique_ptr<HistogramProviders> providers_deleter; | |
482 { | 506 { |
483 base::AutoLock auto_lock(lock_.Get()); | 507 base::AutoLock auto_lock(lock_.Get()); |
484 histograms_deleter.reset(histograms_); | 508 histograms_deleter.reset(histograms_); |
485 callbacks_deleter.reset(callbacks_); | 509 callbacks_deleter.reset(callbacks_); |
486 ranges_deleter.reset(ranges_); | 510 ranges_deleter.reset(ranges_); |
511 providers_deleter.reset(providers_); | |
487 histograms_ = nullptr; | 512 histograms_ = nullptr; |
488 callbacks_ = nullptr; | 513 callbacks_ = nullptr; |
489 ranges_ = nullptr; | 514 ranges_ = nullptr; |
515 providers_ = nullptr; | |
490 } | 516 } |
491 // We are going to leak the histograms and the ranges. | 517 // We are going to leak the histograms and the ranges. |
492 } | 518 } |
493 | 519 |
494 // static | 520 // static |
495 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) { | 521 void StatisticsRecorder::DumpHistogramsToVlog(void* instance) { |
496 std::string output; | 522 std::string output; |
497 StatisticsRecorder::WriteGraph(std::string(), &output); | 523 StatisticsRecorder::WriteGraph(std::string(), &output); |
498 VLOG(1) << output; | 524 VLOG(1) << output; |
499 } | 525 } |
500 | 526 |
501 | 527 |
502 // static | 528 // static |
503 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr; | 529 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr; |
504 // static | 530 // static |
505 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; | 531 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; |
506 // static | 532 // static |
507 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; | 533 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; |
508 // static | 534 // static |
535 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_; | |
536 // static | |
509 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = | 537 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = |
510 LAZY_INSTANCE_INITIALIZER; | 538 LAZY_INSTANCE_INITIALIZER; |
511 | 539 |
512 } // namespace base | 540 } // namespace base |
OLD | NEW |