Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/metrics/file_metrics_provider.h" | 5 #include "components/metrics/file_metrics_provider.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/files/file.h" | 8 #include "base/files/file.h" |
| 9 #include "base/files/file_enumerator.h" | 9 #include "base/files/file_enumerator.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/files/memory_mapped_file.h" | 11 #include "base/files/memory_mapped_file.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_base.h" | 14 #include "base/metrics/histogram_base.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/metrics/persistent_histogram_allocator.h" | 16 #include "base/metrics/persistent_histogram_allocator.h" |
| 17 #include "base/metrics/persistent_memory_allocator.h" | 17 #include "base/metrics/persistent_memory_allocator.h" |
| 18 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
| 19 #include "base/task_runner.h" | 19 #include "base/task_runner.h" |
| 20 #include "base/task_scheduler/post_task.h" | |
| 21 #include "base/task_scheduler/task_traits.h" | |
| 20 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 21 #include "components/metrics/metrics_pref_names.h" | 23 #include "components/metrics/metrics_pref_names.h" |
| 22 #include "components/metrics/metrics_service.h" | 24 #include "components/metrics/metrics_service.h" |
| 23 #include "components/metrics/persistent_system_profile.h" | 25 #include "components/metrics/persistent_system_profile.h" |
| 24 #include "components/prefs/pref_registry_simple.h" | 26 #include "components/prefs/pref_registry_simple.h" |
| 25 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
| 26 | 28 |
| 27 namespace metrics { | 29 namespace metrics { |
| 28 | 30 |
| 29 namespace { | 31 namespace { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 | 88 |
| 87 void DeleteFileWhenPossible(const base::FilePath& path) { | 89 void DeleteFileWhenPossible(const base::FilePath& path) { |
| 88 // Open (with delete) and then immediately close the file by going out of | 90 // Open (with delete) and then immediately close the file by going out of |
| 89 // scope. This is the only cross-platform safe way to delete a file that may | 91 // scope. This is the only cross-platform safe way to delete a file that may |
| 90 // be open elsewhere, a distinct possibility given the asynchronous nature | 92 // be open elsewhere, a distinct possibility given the asynchronous nature |
| 91 // of the delete task. | 93 // of the delete task. |
| 92 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | | 94 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
| 93 base::File::FLAG_DELETE_ON_CLOSE); | 95 base::File::FLAG_DELETE_ON_CLOSE); |
| 94 } | 96 } |
| 95 | 97 |
| 98 // A task runner to use for testing. | |
| 99 base::TaskRunner* g_task_runner_for_testing = nullptr; | |
| 100 | |
| 101 // Returns a task runner appropriate for running background tasks that perform | |
| 102 // file I/O. | |
| 103 scoped_refptr<base::TaskRunner> CreateBackgroundTaskRunner() { | |
| 104 if (g_task_runner_for_testing) | |
| 105 return scoped_refptr<base::TaskRunner>(g_task_runner_for_testing); | |
| 106 | |
| 107 return base::CreateTaskRunnerWithTraits( | |
| 108 {base::MayBlock(), base::TaskPriority::BACKGROUND, | |
| 109 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); | |
|
bcwhite
2017/07/04 14:50:31
I don't think there's anything in here that needs
Ilya Sherman
2017/07/05 18:15:56
Done.
| |
| 110 } | |
| 111 | |
| 96 } // namespace | 112 } // namespace |
| 97 | 113 |
| 98 // This structure stores all the information about the sources being monitored | 114 // This structure stores all the information about the sources being monitored |
| 99 // and their current reporting state. | 115 // and their current reporting state. |
| 100 struct FileMetricsProvider::SourceInfo { | 116 struct FileMetricsProvider::SourceInfo { |
| 101 SourceInfo(SourceType source_type, SourceAssociation source_association) | 117 SourceInfo(SourceType source_type, SourceAssociation source_association) |
| 102 : type(source_type), association(source_association) {} | 118 : type(source_type), association(source_association) {} |
| 103 ~SourceInfo() {} | 119 ~SourceInfo() {} |
| 104 | 120 |
| 105 // How to access this source (file/dir, atomic/active). | 121 // How to access this source (file/dir, atomic/active). |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 126 bool read_complete = false; | 142 bool read_complete = false; |
| 127 | 143 |
| 128 // Once a file has been recognized as needing to be read, it is mapped | 144 // Once a file has been recognized as needing to be read, it is mapped |
| 129 // into memory and assigned to an |allocator| object. | 145 // into memory and assigned to an |allocator| object. |
| 130 std::unique_ptr<base::PersistentHistogramAllocator> allocator; | 146 std::unique_ptr<base::PersistentHistogramAllocator> allocator; |
| 131 | 147 |
| 132 private: | 148 private: |
| 133 DISALLOW_COPY_AND_ASSIGN(SourceInfo); | 149 DISALLOW_COPY_AND_ASSIGN(SourceInfo); |
| 134 }; | 150 }; |
| 135 | 151 |
| 136 FileMetricsProvider::FileMetricsProvider( | 152 FileMetricsProvider::FileMetricsProvider(PrefService* local_state) |
| 137 const scoped_refptr<base::TaskRunner>& task_runner, | 153 : task_runner_(CreateBackgroundTaskRunner()), |
| 138 PrefService* local_state) | |
| 139 : task_runner_(task_runner), | |
| 140 pref_service_(local_state), | 154 pref_service_(local_state), |
| 141 weak_factory_(this) { | 155 weak_factory_(this) { |
| 142 base::StatisticsRecorder::RegisterHistogramProvider( | 156 base::StatisticsRecorder::RegisterHistogramProvider( |
| 143 weak_factory_.GetWeakPtr()); | 157 weak_factory_.GetWeakPtr()); |
| 144 } | 158 } |
| 145 | 159 |
| 146 FileMetricsProvider::~FileMetricsProvider() {} | 160 FileMetricsProvider::~FileMetricsProvider() {} |
| 147 | 161 |
| 148 void FileMetricsProvider::RegisterSource(const base::FilePath& path, | 162 void FileMetricsProvider::RegisterSource(const base::FilePath& path, |
| 149 SourceType type, | 163 SourceType type, |
| 150 SourceAssociation source_association, | 164 SourceAssociation source_association, |
| 151 const base::StringPiece prefs_key) { | 165 const base::StringPiece prefs_key) { |
| 152 DCHECK(thread_checker_.CalledOnValidThread()); | 166 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 153 | 167 |
| 154 // Ensure that kSourceOptions has been filled for this type. | 168 // Ensure that kSourceOptions has been filled for this type. |
| 155 DCHECK_GT(arraysize(kSourceOptions), static_cast<size_t>(type)); | 169 DCHECK_GT(arraysize(kSourceOptions), static_cast<size_t>(type)); |
| 156 | 170 |
| 157 std::unique_ptr<SourceInfo> source(new SourceInfo(type, source_association)); | 171 std::unique_ptr<SourceInfo> source(new SourceInfo(type, source_association)); |
| 158 source->prefs_key = prefs_key.as_string(); | 172 source->prefs_key = prefs_key.as_string(); |
| 159 | 173 |
| 160 switch (source->type) { | 174 switch (source->type) { |
| 161 case SOURCE_HISTOGRAMS_ACTIVE_FILE: | 175 case SOURCE_HISTOGRAMS_ACTIVE_FILE: |
| 162 DCHECK(prefs_key.empty()); | 176 DCHECK(prefs_key.empty()); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 191 } | 205 } |
| 192 | 206 |
| 193 // static | 207 // static |
| 194 void FileMetricsProvider::RegisterPrefs(PrefRegistrySimple* prefs, | 208 void FileMetricsProvider::RegisterPrefs(PrefRegistrySimple* prefs, |
| 195 const base::StringPiece prefs_key) { | 209 const base::StringPiece prefs_key) { |
| 196 prefs->RegisterInt64Pref(metrics::prefs::kMetricsLastSeenPrefix + | 210 prefs->RegisterInt64Pref(metrics::prefs::kMetricsLastSeenPrefix + |
| 197 prefs_key.as_string(), 0); | 211 prefs_key.as_string(), 0); |
| 198 } | 212 } |
| 199 | 213 |
| 200 // static | 214 // static |
| 215 void FileMetricsProvider::SetTaskRunnerForTesting( | |
| 216 const scoped_refptr<base::TaskRunner>& task_runner) { | |
| 217 g_task_runner_for_testing = task_runner.get(); | |
|
bcwhite
2017/07/04 14:50:31
Delete the existing one if set.
Ilya Sherman
2017/07/05 18:15:56
There's no ownership, so it doesn't make sense to
bcwhite
2017/07/05 18:31:51
Acknowledged.
| |
| 218 } | |
| 219 | |
| 220 // static | |
| 201 bool FileMetricsProvider::LocateNextFileInDirectory(SourceInfo* source) { | 221 bool FileMetricsProvider::LocateNextFileInDirectory(SourceInfo* source) { |
| 202 DCHECK_EQ(SOURCE_HISTOGRAMS_ATOMIC_DIR, source->type); | 222 DCHECK_EQ(SOURCE_HISTOGRAMS_ATOMIC_DIR, source->type); |
| 203 DCHECK(!source->directory.empty()); | 223 DCHECK(!source->directory.empty()); |
| 204 | 224 |
| 205 // Open the directory and find all the files, remembering the oldest that | 225 // Open the directory and find all the files, remembering the oldest that |
| 206 // has not been read. They can be removed and/or ignored if they're older | 226 // has not been read. They can be removed and/or ignored if they're older |
| 207 // than the last-check time. | 227 // than the last-check time. |
| 208 base::Time oldest_file_time = base::Time::Now(); | 228 base::Time oldest_file_time = base::Time::Now(); |
| 209 base::FilePath oldest_file_path; | 229 base::FilePath oldest_file_path; |
| 210 base::FilePath file_path; | 230 base::FilePath file_path; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 snapshot_manager->PrepareFinalDelta(histogram.get()); | 451 snapshot_manager->PrepareFinalDelta(histogram.get()); |
| 432 ++histogram_count; | 452 ++histogram_count; |
| 433 } | 453 } |
| 434 | 454 |
| 435 source->read_complete = true; | 455 source->read_complete = true; |
| 436 DVLOG(1) << "Reported " << histogram_count << " histograms from " | 456 DVLOG(1) << "Reported " << histogram_count << " histograms from " |
| 437 << source->path.value(); | 457 << source->path.value(); |
| 438 } | 458 } |
| 439 | 459 |
| 440 void FileMetricsProvider::ScheduleSourcesCheck() { | 460 void FileMetricsProvider::ScheduleSourcesCheck() { |
| 441 DCHECK(thread_checker_.CalledOnValidThread()); | 461 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 442 if (sources_to_check_.empty()) | 462 if (sources_to_check_.empty()) |
| 443 return; | 463 return; |
| 444 | 464 |
| 445 // Create an independent list of sources for checking. This will be Owned() | 465 // Create an independent list of sources for checking. This will be Owned() |
| 446 // by the reply call given to the task-runner, to be deleted when that call | 466 // by the reply call given to the task-runner, to be deleted when that call |
| 447 // has returned. It is also passed Unretained() to the task itself, safe | 467 // has returned. It is also passed Unretained() to the task itself, safe |
| 448 // because that must complete before the reply runs. | 468 // because that must complete before the reply runs. |
| 449 SourceInfoList* check_list = new SourceInfoList(); | 469 SourceInfoList* check_list = new SourceInfoList(); |
| 450 std::swap(sources_to_check_, *check_list); | 470 std::swap(sources_to_check_, *check_list); |
| 451 task_runner_->PostTaskAndReply( | 471 task_runner_->PostTaskAndReply( |
| 452 FROM_HERE, | 472 FROM_HERE, |
| 453 base::Bind(&FileMetricsProvider::CheckAndMergeMetricSourcesOnTaskRunner, | 473 base::Bind(&FileMetricsProvider::CheckAndMergeMetricSourcesOnTaskRunner, |
| 454 base::Unretained(check_list)), | 474 base::Unretained(check_list)), |
| 455 base::Bind(&FileMetricsProvider::RecordSourcesChecked, | 475 base::Bind(&FileMetricsProvider::RecordSourcesChecked, |
| 456 weak_factory_.GetWeakPtr(), base::Owned(check_list))); | 476 weak_factory_.GetWeakPtr(), base::Owned(check_list))); |
| 457 } | 477 } |
| 458 | 478 |
| 459 void FileMetricsProvider::RecordSourcesChecked(SourceInfoList* checked) { | 479 void FileMetricsProvider::RecordSourcesChecked(SourceInfoList* checked) { |
| 460 DCHECK(thread_checker_.CalledOnValidThread()); | 480 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 461 | 481 |
| 462 // Sources that still have an allocator at this point are read/write "active" | 482 // Sources that still have an allocator at this point are read/write "active" |
| 463 // files that may need their contents merged on-demand. If there is no | 483 // files that may need their contents merged on-demand. If there is no |
| 464 // allocator (not a read/write file) but a read was done on the task-runner, | 484 // allocator (not a read/write file) but a read was done on the task-runner, |
| 465 // try again immediately to see if more is available (in a directory of | 485 // try again immediately to see if more is available (in a directory of |
| 466 // files). Otherwise, remember the source for checking again at a later time. | 486 // files). Otherwise, remember the source for checking again at a later time. |
| 467 bool did_read = false; | 487 bool did_read = false; |
| 468 for (auto iter = checked->begin(); iter != checked->end();) { | 488 for (auto iter = checked->begin(); iter != checked->end();) { |
| 469 auto temp = iter++; | 489 auto temp = iter++; |
| 470 SourceInfo* source = temp->get(); | 490 SourceInfo* source = temp->get(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 491 // is possible. | 511 // is possible. |
| 492 if (did_read) | 512 if (did_read) |
| 493 ScheduleSourcesCheck(); | 513 ScheduleSourcesCheck(); |
| 494 } | 514 } |
| 495 | 515 |
| 496 void FileMetricsProvider::DeleteFileAsync(const base::FilePath& path) { | 516 void FileMetricsProvider::DeleteFileAsync(const base::FilePath& path) { |
| 497 task_runner_->PostTask(FROM_HERE, base::Bind(DeleteFileWhenPossible, path)); | 517 task_runner_->PostTask(FROM_HERE, base::Bind(DeleteFileWhenPossible, path)); |
| 498 } | 518 } |
| 499 | 519 |
| 500 void FileMetricsProvider::RecordSourceAsRead(SourceInfo* source) { | 520 void FileMetricsProvider::RecordSourceAsRead(SourceInfo* source) { |
| 501 DCHECK(thread_checker_.CalledOnValidThread()); | 521 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 502 | 522 |
| 503 // Persistently record the "last seen" timestamp of the source file to | 523 // Persistently record the "last seen" timestamp of the source file to |
| 504 // ensure that the file is never read again unless it is modified again. | 524 // ensure that the file is never read again unless it is modified again. |
| 505 if (pref_service_ && !source->prefs_key.empty()) { | 525 if (pref_service_ && !source->prefs_key.empty()) { |
| 506 pref_service_->SetInt64( | 526 pref_service_->SetInt64( |
| 507 metrics::prefs::kMetricsLastSeenPrefix + source->prefs_key, | 527 metrics::prefs::kMetricsLastSeenPrefix + source->prefs_key, |
| 508 source->last_seen.ToInternalValue()); | 528 source->last_seen.ToInternalValue()); |
| 509 } | 529 } |
| 510 } | 530 } |
| 511 | 531 |
| 512 void FileMetricsProvider::OnDidCreateMetricsLog() { | 532 void FileMetricsProvider::OnDidCreateMetricsLog() { |
| 513 DCHECK(thread_checker_.CalledOnValidThread()); | 533 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 514 | 534 |
| 515 // Schedule a check to see if there are new metrics to load. If so, they | 535 // Schedule a check to see if there are new metrics to load. If so, they |
| 516 // will be reported during the next collection run after this one. The | 536 // will be reported during the next collection run after this one. The |
| 517 // check is run off of the worker-pool so as to not cause delays on the | 537 // check is run off of the worker-pool so as to not cause delays on the |
| 518 // main UI thread (which is currently where metric collection is done). | 538 // main UI thread (which is currently where metric collection is done). |
| 519 ScheduleSourcesCheck(); | 539 ScheduleSourcesCheck(); |
| 520 | 540 |
| 521 // Clear any data for initial metrics since they're always reported | 541 // Clear any data for initial metrics since they're always reported |
| 522 // before the first call to this method. It couldn't be released after | 542 // before the first call to this method. It couldn't be released after |
| 523 // being reported in RecordInitialHistogramSnapshots because the data | 543 // being reported in RecordInitialHistogramSnapshots because the data |
| 524 // will continue to be used by the caller after that method returns. Once | 544 // will continue to be used by the caller after that method returns. Once |
| 525 // here, though, all actions to be done on the data have been completed. | 545 // here, though, all actions to be done on the data have been completed. |
| 526 for (const std::unique_ptr<SourceInfo>& source : sources_for_previous_run_) | 546 for (const std::unique_ptr<SourceInfo>& source : sources_for_previous_run_) |
| 527 DeleteFileAsync(source->path); | 547 DeleteFileAsync(source->path); |
| 528 sources_for_previous_run_.clear(); | 548 sources_for_previous_run_.clear(); |
| 529 } | 549 } |
| 530 | 550 |
| 531 bool FileMetricsProvider::ProvideIndependentMetrics( | 551 bool FileMetricsProvider::ProvideIndependentMetrics( |
| 532 SystemProfileProto* system_profile_proto, | 552 SystemProfileProto* system_profile_proto, |
| 533 base::HistogramSnapshotManager* snapshot_manager) { | 553 base::HistogramSnapshotManager* snapshot_manager) { |
| 534 DCHECK(thread_checker_.CalledOnValidThread()); | 554 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 535 | 555 |
| 536 while (!sources_with_profile_.empty()) { | 556 while (!sources_with_profile_.empty()) { |
| 537 SourceInfo* source = sources_with_profile_.begin()->get(); | 557 SourceInfo* source = sources_with_profile_.begin()->get(); |
| 538 DCHECK(source->allocator); | 558 DCHECK(source->allocator); |
| 539 | 559 |
| 540 bool success = false; | 560 bool success = false; |
| 541 RecordEmbeddedProfileResult(EMBEDDED_PROFILE_ATTEMPT); | 561 RecordEmbeddedProfileResult(EMBEDDED_PROFILE_ATTEMPT); |
| 542 if (PersistentSystemProfile::GetSystemProfile( | 562 if (PersistentSystemProfile::GetSystemProfile( |
| 543 *source->allocator->memory_allocator(), system_profile_proto)) { | 563 *source->allocator->memory_allocator(), system_profile_proto)) { |
| 544 RecordHistogramSnapshotsFromSource(snapshot_manager, source); | 564 RecordHistogramSnapshotsFromSource(snapshot_manager, source); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 555 sources_to_check_.splice(sources_to_check_.end(), sources_with_profile_, | 575 sources_to_check_.splice(sources_to_check_.end(), sources_with_profile_, |
| 556 sources_with_profile_.begin()); | 576 sources_with_profile_.begin()); |
| 557 if (success) | 577 if (success) |
| 558 return true; | 578 return true; |
| 559 } | 579 } |
| 560 | 580 |
| 561 return false; | 581 return false; |
| 562 } | 582 } |
| 563 | 583 |
| 564 bool FileMetricsProvider::HasInitialStabilityMetrics() { | 584 bool FileMetricsProvider::HasInitialStabilityMetrics() { |
| 565 DCHECK(thread_checker_.CalledOnValidThread()); | 585 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 566 | 586 |
| 567 // Measure the total time spent checking all sources as well as the time | 587 // Measure the total time spent checking all sources as well as the time |
| 568 // per individual file. This method is called during startup and thus blocks | 588 // per individual file. This method is called during startup and thus blocks |
| 569 // the initial showing of the browser window so it's important to know the | 589 // the initial showing of the browser window so it's important to know the |
| 570 // total delay. | 590 // total delay. |
| 571 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.InitialCheckTime.Total"); | 591 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.InitialCheckTime.Total"); |
| 572 | 592 |
| 573 // Check all sources for previous run to see if they need to be read. | 593 // Check all sources for previous run to see if they need to be read. |
| 574 for (auto iter = sources_for_previous_run_.begin(); | 594 for (auto iter = sources_for_previous_run_.begin(); |
| 575 iter != sources_for_previous_run_.end();) { | 595 iter != sources_for_previous_run_.end();) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 sources_for_previous_run_, temp); | 631 sources_for_previous_run_, temp); |
| 612 } | 632 } |
| 613 } | 633 } |
| 614 } | 634 } |
| 615 | 635 |
| 616 return !sources_for_previous_run_.empty(); | 636 return !sources_for_previous_run_.empty(); |
| 617 } | 637 } |
| 618 | 638 |
| 619 void FileMetricsProvider::RecordInitialHistogramSnapshots( | 639 void FileMetricsProvider::RecordInitialHistogramSnapshots( |
| 620 base::HistogramSnapshotManager* snapshot_manager) { | 640 base::HistogramSnapshotManager* snapshot_manager) { |
| 621 DCHECK(thread_checker_.CalledOnValidThread()); | 641 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 622 | 642 |
| 623 // Measure the total time spent processing all sources as well as the time | 643 // Measure the total time spent processing all sources as well as the time |
| 624 // per individual file. This method is called during startup and thus blocks | 644 // per individual file. This method is called during startup and thus blocks |
| 625 // the initial showing of the browser window so it's important to know the | 645 // the initial showing of the browser window so it's important to know the |
| 626 // total delay. | 646 // total delay. |
| 627 SCOPED_UMA_HISTOGRAM_TIMER( | 647 SCOPED_UMA_HISTOGRAM_TIMER( |
| 628 "UMA.FileMetricsProvider.InitialSnapshotTime.Total"); | 648 "UMA.FileMetricsProvider.InitialSnapshotTime.Total"); |
| 629 | 649 |
| 630 for (const std::unique_ptr<SourceInfo>& source : sources_for_previous_run_) { | 650 for (const std::unique_ptr<SourceInfo>& source : sources_for_previous_run_) { |
| 631 SCOPED_UMA_HISTOGRAM_TIMER( | 651 SCOPED_UMA_HISTOGRAM_TIMER( |
| 632 "UMA.FileMetricsProvider.InitialSnapshotTime.File"); | 652 "UMA.FileMetricsProvider.InitialSnapshotTime.File"); |
| 633 | 653 |
| 634 // The source needs to have an allocator attached to it in order to read | 654 // The source needs to have an allocator attached to it in order to read |
| 635 // histograms out of it. | 655 // histograms out of it. |
| 636 DCHECK(!source->read_complete); | 656 DCHECK(!source->read_complete); |
| 637 DCHECK(source->allocator); | 657 DCHECK(source->allocator); |
| 638 | 658 |
| 639 // Dump all histograms contained within the source to the snapshot-manager. | 659 // Dump all histograms contained within the source to the snapshot-manager. |
| 640 RecordHistogramSnapshotsFromSource(snapshot_manager, source.get()); | 660 RecordHistogramSnapshotsFromSource(snapshot_manager, source.get()); |
| 641 | 661 |
| 642 // Update the last-seen time so it isn't read again unless it changes. | 662 // Update the last-seen time so it isn't read again unless it changes. |
| 643 RecordSourceAsRead(source.get()); | 663 RecordSourceAsRead(source.get()); |
| 644 } | 664 } |
| 645 } | 665 } |
| 646 | 666 |
| 647 void FileMetricsProvider::MergeHistogramDeltas() { | 667 void FileMetricsProvider::MergeHistogramDeltas() { |
| 648 DCHECK(thread_checker_.CalledOnValidThread()); | 668 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 649 | 669 |
| 650 // Measure the total time spent processing all sources as well as the time | 670 // Measure the total time spent processing all sources as well as the time |
| 651 // per individual file. This method is called on the UI thread so it's | 671 // per individual file. This method is called on the UI thread so it's |
| 652 // important to know how much total "jank" may be introduced. | 672 // important to know how much total "jank" may be introduced. |
| 653 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.Total"); | 673 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.Total"); |
| 654 | 674 |
| 655 for (std::unique_ptr<SourceInfo>& source : sources_mapped_) { | 675 for (std::unique_ptr<SourceInfo>& source : sources_mapped_) { |
| 656 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.File"); | 676 SCOPED_UMA_HISTOGRAM_TIMER("UMA.FileMetricsProvider.SnapshotTime.File"); |
| 657 MergeHistogramDeltasFromSource(source.get()); | 677 MergeHistogramDeltasFromSource(source.get()); |
| 658 } | 678 } |
| 659 } | 679 } |
| 660 | 680 |
| 661 } // namespace metrics | 681 } // namespace metrics |
| OLD | NEW |