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 "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" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 bool HistogramNameLesser(const base::HistogramBase* a, | 25 bool HistogramNameLesser(const base::HistogramBase* a, |
26 const base::HistogramBase* b) { | 26 const base::HistogramBase* b) { |
27 return a->histogram_name() < b->histogram_name(); | 27 return a->histogram_name() < b->histogram_name(); |
28 } | 28 } |
29 | 29 |
30 } // namespace | 30 } // namespace |
31 | 31 |
32 namespace base { | 32 namespace base { |
33 | 33 |
| 34 StatisticsRecorder::HistogramIterator::HistogramIterator( |
| 35 const HistogramMap::iterator& iter, bool include_persistent) |
| 36 : iter_(iter), |
| 37 include_persistent_(include_persistent) { |
| 38 } |
| 39 |
| 40 StatisticsRecorder::HistogramIterator::HistogramIterator( |
| 41 const HistogramIterator& rhs) |
| 42 : iter_(rhs.iter_), |
| 43 include_persistent_(rhs.include_persistent_) { |
| 44 } |
| 45 |
| 46 StatisticsRecorder::HistogramIterator::~HistogramIterator() {} |
| 47 |
| 48 StatisticsRecorder::HistogramIterator& |
| 49 StatisticsRecorder::HistogramIterator::operator++() { |
| 50 const HistogramMap::iterator histograms_end = histograms_->end(); |
| 51 while (iter_ != histograms_end) { |
| 52 ++iter_; |
| 53 if (iter_ == histograms_end) |
| 54 break; |
| 55 if (!include_persistent_ && (iter_->second->flags() & |
| 56 HistogramBase::kIsPersistent)) { |
| 57 continue; |
| 58 } |
| 59 break; |
| 60 } |
| 61 return *this; |
| 62 } |
| 63 |
34 // static | 64 // static |
35 void StatisticsRecorder::Initialize() { | 65 void StatisticsRecorder::Initialize() { |
36 // Ensure that an instance of the StatisticsRecorder object is created. | 66 // Ensure that an instance of the StatisticsRecorder object is created. |
37 g_statistics_recorder_.Get(); | 67 g_statistics_recorder_.Get(); |
38 } | 68 } |
39 | 69 |
40 // static | 70 // static |
41 bool StatisticsRecorder::IsActive() { | 71 bool StatisticsRecorder::IsActive() { |
42 if (lock_ == NULL) | 72 if (lock_ == NULL) |
43 return false; | 73 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
59 } | 89 } |
60 | 90 |
61 HistogramBase* histogram_to_delete = NULL; | 91 HistogramBase* histogram_to_delete = NULL; |
62 HistogramBase* histogram_to_return = NULL; | 92 HistogramBase* histogram_to_return = NULL; |
63 { | 93 { |
64 base::AutoLock auto_lock(*lock_); | 94 base::AutoLock auto_lock(*lock_); |
65 if (histograms_ == NULL) { | 95 if (histograms_ == NULL) { |
66 histogram_to_return = histogram; | 96 histogram_to_return = histogram; |
67 } else { | 97 } else { |
68 const std::string& name = histogram->histogram_name(); | 98 const std::string& name = histogram->histogram_name(); |
69 uint64_t name_hash = histogram->name_hash(); | 99 const uint64_t name_hash = histogram->name_hash(); |
| 100 DCHECK_NE(0U, name_hash); |
70 HistogramMap::iterator it = histograms_->find(name_hash); | 101 HistogramMap::iterator it = histograms_->find(name_hash); |
71 if (histograms_->end() == it) { | 102 if (histograms_->end() == it) { |
72 (*histograms_)[name_hash] = histogram; | 103 (*histograms_)[name_hash] = histogram; |
73 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 | 104 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 |
74 // If there are callbacks for this histogram, we set the kCallbackExists | 105 // If there are callbacks for this histogram, we set the kCallbackExists |
75 // flag. | 106 // flag. |
76 auto callback_iterator = callbacks_->find(name); | 107 auto callback_iterator = callbacks_->find(name); |
77 if (callback_iterator != callbacks_->end()) { | 108 if (callback_iterator != callbacks_->end()) { |
78 if (!callback_iterator->second.is_null()) | 109 if (!callback_iterator->second.is_null()) |
79 histogram->SetFlags(HistogramBase::kCallbackExists); | 110 histogram->SetFlags(HistogramBase::kCallbackExists); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 if (lock_ == NULL) | 288 if (lock_ == NULL) |
258 return false; | 289 return false; |
259 base::AutoLock auto_lock(*lock_); | 290 base::AutoLock auto_lock(*lock_); |
260 if (histograms_ == NULL) | 291 if (histograms_ == NULL) |
261 return false; | 292 return false; |
262 | 293 |
263 if (ContainsKey(*callbacks_, name)) | 294 if (ContainsKey(*callbacks_, name)) |
264 return false; | 295 return false; |
265 callbacks_->insert(std::make_pair(name, cb)); | 296 callbacks_->insert(std::make_pair(name, cb)); |
266 | 297 |
267 HistogramMap::iterator it = histograms_->find(HashMetricName(name)); | 298 auto it = histograms_->find(HashMetricName(name)); |
268 if (it != histograms_->end()) { | 299 if (it != histograms_->end()) { |
269 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision"; | 300 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision"; |
270 it->second->SetFlags(HistogramBase::kCallbackExists); | 301 it->second->SetFlags(HistogramBase::kCallbackExists); |
271 } | 302 } |
272 | 303 |
273 return true; | 304 return true; |
274 } | 305 } |
275 | 306 |
276 // static | 307 // static |
277 void StatisticsRecorder::ClearCallback(const std::string& name) { | 308 void StatisticsRecorder::ClearCallback(const std::string& name) { |
278 if (lock_ == NULL) | 309 if (lock_ == NULL) |
279 return; | 310 return; |
280 base::AutoLock auto_lock(*lock_); | 311 base::AutoLock auto_lock(*lock_); |
281 if (histograms_ == NULL) | 312 if (histograms_ == NULL) |
282 return; | 313 return; |
283 | 314 |
284 callbacks_->erase(name); | 315 callbacks_->erase(name); |
285 | 316 |
286 // We also clear the flag from the histogram (if it exists). | 317 // We also clear the flag from the histogram (if it exists). |
287 HistogramMap::iterator it = histograms_->find(HashMetricName(name)); | 318 auto it = histograms_->find(HashMetricName(name)); |
288 if (it != histograms_->end()) { | 319 if (it != histograms_->end()) { |
289 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision"; | 320 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision"; |
290 it->second->ClearFlags(HistogramBase::kCallbackExists); | 321 it->second->ClearFlags(HistogramBase::kCallbackExists); |
291 } | 322 } |
292 } | 323 } |
293 | 324 |
294 // static | 325 // static |
295 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback( | 326 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback( |
296 const std::string& name) { | 327 const std::string& name) { |
297 if (lock_ == NULL) | 328 if (lock_ == NULL) |
298 return OnSampleCallback(); | 329 return OnSampleCallback(); |
299 base::AutoLock auto_lock(*lock_); | 330 base::AutoLock auto_lock(*lock_); |
300 if (histograms_ == NULL) | 331 if (histograms_ == NULL) |
301 return OnSampleCallback(); | 332 return OnSampleCallback(); |
302 | 333 |
303 auto callback_iterator = callbacks_->find(name); | 334 auto callback_iterator = callbacks_->find(name); |
304 return callback_iterator != callbacks_->end() ? callback_iterator->second | 335 return callback_iterator != callbacks_->end() ? callback_iterator->second |
305 : OnSampleCallback(); | 336 : OnSampleCallback(); |
306 } | 337 } |
307 | 338 |
308 // private static | 339 // static |
| 340 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin( |
| 341 bool include_persistent) { |
| 342 return HistogramIterator(histograms_->begin(), include_persistent); |
| 343 } |
| 344 |
| 345 // static |
| 346 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() { |
| 347 return HistogramIterator(histograms_->end(), true); |
| 348 } |
| 349 |
| 350 // static |
309 void StatisticsRecorder::GetSnapshot(const std::string& query, | 351 void StatisticsRecorder::GetSnapshot(const std::string& query, |
310 Histograms* snapshot) { | 352 Histograms* snapshot) { |
311 if (lock_ == NULL) | 353 if (lock_ == NULL) |
312 return; | 354 return; |
313 base::AutoLock auto_lock(*lock_); | 355 base::AutoLock auto_lock(*lock_); |
314 if (histograms_ == NULL) | 356 if (histograms_ == NULL) |
315 return; | 357 return; |
316 | 358 |
317 for (const auto& entry : *histograms_) { | 359 for (const auto& entry : *histograms_) { |
318 if (entry.second->histogram_name().find(query) != std::string::npos) | 360 if (entry.second->histogram_name().find(query) != std::string::npos) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 // static | 417 // static |
376 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 418 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
377 // static | 419 // static |
378 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; | 420 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; |
379 // static | 421 // static |
380 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; | 422 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; |
381 // static | 423 // static |
382 base::Lock* StatisticsRecorder::lock_ = NULL; | 424 base::Lock* StatisticsRecorder::lock_ = NULL; |
383 | 425 |
384 } // namespace base | 426 } // namespace base |
OLD | NEW |