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

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

Issue 1876053002: Run SR tests both with and without persistent allocator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix use-after-free in test Created 4 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/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 <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 19 matching lines...) Expand all
30 } 30 }
31 31
32 } // namespace 32 } // namespace
33 33
34 namespace base { 34 namespace base {
35 35
36 StatisticsRecorder::HistogramIterator::HistogramIterator( 36 StatisticsRecorder::HistogramIterator::HistogramIterator(
37 const HistogramMap::iterator& iter, bool include_persistent) 37 const HistogramMap::iterator& iter, bool include_persistent)
38 : iter_(iter), 38 : iter_(iter),
39 include_persistent_(include_persistent) { 39 include_persistent_(include_persistent) {
40 // The starting location could point to a persistent histogram when such
41 // is not wanted. If so, skip it.
42 if (!include_persistent_ && iter_ != histograms_->end() &&
43 (iter_->second->flags() & HistogramBase::kIsPersistent)) {
44 // This operator will continue to skip until a non-persistent histogram
45 // is found.
46 operator++();
47 }
40 } 48 }
41 49
42 StatisticsRecorder::HistogramIterator::HistogramIterator( 50 StatisticsRecorder::HistogramIterator::HistogramIterator(
43 const HistogramIterator& rhs) 51 const HistogramIterator& rhs)
44 : iter_(rhs.iter_), 52 : iter_(rhs.iter_),
45 include_persistent_(rhs.include_persistent_) { 53 include_persistent_(rhs.include_persistent_) {
46 } 54 }
47 55
48 StatisticsRecorder::HistogramIterator::~HistogramIterator() {} 56 StatisticsRecorder::HistogramIterator::~HistogramIterator() {}
49 57
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 288
281 for (const auto& entry : *ranges_) { 289 for (const auto& entry : *ranges_) {
282 for (const auto& range_entry : *entry.second) { 290 for (const auto& range_entry : *entry.second) {
283 output->push_back(range_entry); 291 output->push_back(range_entry);
284 } 292 }
285 } 293 }
286 } 294 }
287 295
288 // static 296 // static
289 HistogramBase* StatisticsRecorder::FindHistogram(base::StringPiece name) { 297 HistogramBase* StatisticsRecorder::FindHistogram(base::StringPiece name) {
290 if (lock_ == NULL)
291 return NULL;
292
293 // Import histograms from known persistent storage. Histograms could have
294 // been added by other processes and they must be fetched and recognized
295 // locally. If the persistent memory segment is not shared between processes,
296 // this call does nothing.
297 // This must be called *before* the lock is acquired below because it will 298 // This must be called *before* the lock is acquired below because it will
298 // call back into this object to register histograms. Those called methods 299 // call back into this object to register histograms. Those called methods
299 // will acquire the lock at that time. 300 // will acquire the lock at that time.
300 GlobalHistogramAllocator* allocator = GlobalHistogramAllocator::Get(); 301 ImportGlobalPersistentHistograms();
301 if (allocator)
302 allocator->ImportHistogramsToStatisticsRecorder();
303 302
303 if (lock_ == NULL)
304 return NULL;
304 base::AutoLock auto_lock(*lock_); 305 base::AutoLock auto_lock(*lock_);
305 if (histograms_ == NULL) 306 if (histograms_ == NULL)
306 return NULL; 307 return NULL;
307 308
308 HistogramMap::iterator it = histograms_->find(name); 309 HistogramMap::iterator it = histograms_->find(name);
309 if (histograms_->end() == it) 310 if (histograms_->end() == it)
310 return NULL; 311 return NULL;
311 return it->second; 312 return it->second;
312 } 313 }
313 314
314 // static 315 // static
315 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin( 316 StatisticsRecorder::HistogramIterator StatisticsRecorder::begin(
316 bool include_persistent) { 317 bool include_persistent) {
318 ImportGlobalPersistentHistograms();
317 return HistogramIterator(histograms_->begin(), include_persistent); 319 return HistogramIterator(histograms_->begin(), include_persistent);
318 } 320 }
319 321
320 // static 322 // static
321 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() { 323 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() {
322 return HistogramIterator(histograms_->end(), true); 324 return HistogramIterator(histograms_->end(), true);
323 } 325 }
324 326
325 // static 327 // static
326 void StatisticsRecorder::GetSnapshot(const std::string& query, 328 void StatisticsRecorder::GetSnapshot(const std::string& query,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 // can't "delete" it; call the destructor explicitly. 418 // can't "delete" it; call the destructor explicitly.
417 DCHECK(g_statistics_recorder_.private_instance_); 419 DCHECK(g_statistics_recorder_.private_instance_);
418 g_statistics_recorder_.Get().~StatisticsRecorder(); 420 g_statistics_recorder_.Get().~StatisticsRecorder();
419 421
420 // Now the ugly part. There's no official way to release a LazyInstance once 422 // Now the ugly part. There's no official way to release a LazyInstance once
421 // created so it's necessary to clear out an internal variable which 423 // created so it's necessary to clear out an internal variable which
422 // shouldn't be publicly visible but is for initialization reasons. 424 // shouldn't be publicly visible but is for initialization reasons.
423 g_statistics_recorder_.private_instance_ = 0; 425 g_statistics_recorder_.private_instance_ = 0;
424 } 426 }
425 427
428 // static
429 void StatisticsRecorder::ImportGlobalPersistentHistograms() {
430 if (lock_ == NULL)
431 return;
432
433 // Import histograms from known persistent storage. Histograms could have
434 // been added by other processes and they must be fetched and recognized
435 // locally. If the persistent memory segment is not shared between processes,
436 // this call does nothing.
437 GlobalHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
438 if (allocator)
439 allocator->ImportHistogramsToStatisticsRecorder();
440 }
441
426 // This singleton instance should be started during the single threaded portion 442 // This singleton instance should be started during the single threaded portion
427 // of main(), and hence it is not thread safe. It initializes globals to 443 // of main(), and hence it is not thread safe. It initializes globals to
428 // provide support for all future calls. 444 // provide support for all future calls.
429 StatisticsRecorder::StatisticsRecorder() { 445 StatisticsRecorder::StatisticsRecorder() {
430 if (lock_ == NULL) { 446 if (lock_ == NULL) {
431 // This will leak on purpose. It's the only way to make sure we won't race 447 // This will leak on purpose. It's the only way to make sure we won't race
432 // against the static uninitialization of the module while one of our 448 // against the static uninitialization of the module while one of our
433 // static methods relying on the lock get called at an inappropriate time 449 // static methods relying on the lock get called at an inappropriate time
434 // during the termination phase. Since it's a static data member, we will 450 // during the termination phase. Since it's a static data member, we will
435 // leak one per process, which would be similar to the instance allocated 451 // leak one per process, which would be similar to the instance allocated
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 // static 501 // static
486 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 502 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
487 // static 503 // static
488 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; 504 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
489 // static 505 // static
490 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; 506 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
491 // static 507 // static
492 base::Lock* StatisticsRecorder::lock_ = NULL; 508 base::Lock* StatisticsRecorder::lock_ = NULL;
493 509
494 } // namespace base 510 } // 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