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

Side by Side Diff: base/tracked_objects.cc

Issue 985773002: Introducing phased profiling framework (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@write_to_file
Patch Set: Fixing Android compile errors. Created 5 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/tracked_objects.h ('k') | base/tracked_objects_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/tracked_objects.h" 5 #include "base/tracked_objects.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 return; 383 return;
384 } 384 }
385 // We must NOT do any allocations during this callback. 385 // We must NOT do any allocations during this callback.
386 // Using the simple linked lists avoids all allocations. 386 // Using the simple linked lists avoids all allocations.
387 DCHECK_EQ(this->next_retired_worker_, reinterpret_cast<ThreadData*>(NULL)); 387 DCHECK_EQ(this->next_retired_worker_, reinterpret_cast<ThreadData*>(NULL));
388 this->next_retired_worker_ = first_retired_worker_; 388 this->next_retired_worker_ = first_retired_worker_;
389 first_retired_worker_ = this; 389 first_retired_worker_ = this;
390 } 390 }
391 391
392 // static 392 // static
393 void ThreadData::Snapshot(ProcessDataSnapshot* process_data) { 393 void ThreadData::Snapshot(ProcessDataSnapshot* process_data_snapshot) {
394 // Add births that have run to completion to |collected_data|. 394 ThreadData::SnapshotCurrentPhase(
395 // |birth_counts| tracks the total number of births recorded at each location 395 &process_data_snapshot->phased_process_data_snapshots[0]);
396 // for which we have not seen a death count.
397 BirthCountMap birth_counts;
398 ThreadData::SnapshotAllExecutedTasks(process_data, &birth_counts);
399
400 // Add births that are still active -- i.e. objects that have tallied a birth,
401 // but have not yet tallied a matching death, and hence must be either
402 // running, queued up, or being held in limbo for future posting.
403 for (BirthCountMap::const_iterator it = birth_counts.begin();
404 it != birth_counts.end(); ++it) {
405 if (it->second > 0) {
406 process_data->tasks.push_back(
407 TaskSnapshot(*it->first, DeathData(it->second), "Still_Alive"));
408 }
409 }
410 } 396 }
411 397
412 Births* ThreadData::TallyABirth(const Location& location) { 398 Births* ThreadData::TallyABirth(const Location& location) {
413 BirthMap::iterator it = birth_map_.find(location); 399 BirthMap::iterator it = birth_map_.find(location);
414 Births* child; 400 Births* child;
415 if (it != birth_map_.end()) { 401 if (it != birth_map_.end()) {
416 child = it->second; 402 child = it->second;
417 child->RecordBirth(); 403 child->RecordBirth();
418 } else { 404 } else {
419 child = new Births(location, *this); // Leak this. 405 child = new Births(location, *this); // Leak this.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 557
572 ThreadData* current_thread_data = stopwatch.GetThreadData(); 558 ThreadData* current_thread_data = stopwatch.GetThreadData();
573 if (!current_thread_data) 559 if (!current_thread_data)
574 return; 560 return;
575 561
576 int32 queue_duration = 0; 562 int32 queue_duration = 0;
577 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch); 563 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch);
578 } 564 }
579 565
580 // static 566 // static
581 void ThreadData::SnapshotAllExecutedTasks(ProcessDataSnapshot* process_data, 567 void ThreadData::SnapshotAllExecutedTasks(
582 BirthCountMap* birth_counts) { 568 ProcessDataPhaseSnapshot* process_data_phase,
569 BirthCountMap* birth_counts) {
583 if (!kTrackAllTaskObjects) 570 if (!kTrackAllTaskObjects)
584 return; // Not compiled in. 571 return; // Not compiled in.
585 572
586 // Get an unchanging copy of a ThreadData list. 573 // Get an unchanging copy of a ThreadData list.
587 ThreadData* my_list = ThreadData::first(); 574 ThreadData* my_list = ThreadData::first();
588 575
589 // Gather data serially. 576 // Gather data serially.
590 // This hackish approach *can* get some slighly corrupt tallies, as we are 577 // This hackish approach *can* get some slighly corrupt tallies, as we are
591 // grabbing values without the protection of a lock, but it has the advantage 578 // grabbing values without the protection of a lock, but it has the advantage
592 // of working even with threads that don't have message loops. If a user 579 // of working even with threads that don't have message loops. If a user
593 // sees any strangeness, they can always just run their stats gathering a 580 // sees any strangeness, they can always just run their stats gathering a
594 // second time. 581 // second time.
595 for (ThreadData* thread_data = my_list; 582 for (ThreadData* thread_data = my_list;
596 thread_data; 583 thread_data;
597 thread_data = thread_data->next()) { 584 thread_data = thread_data->next()) {
598 thread_data->SnapshotExecutedTasks(process_data, birth_counts); 585 thread_data->SnapshotExecutedTasks(process_data_phase, birth_counts);
599 } 586 }
600 } 587 }
601 588
602 void ThreadData::SnapshotExecutedTasks(ProcessDataSnapshot* process_data, 589 // static
603 BirthCountMap* birth_counts) { 590 void ThreadData::SnapshotCurrentPhase(
591 ProcessDataPhaseSnapshot* process_data_phase) {
592 // Add births that have run to completion to |collected_data|.
593 // |birth_counts| tracks the total number of births recorded at each location
594 // for which we have not seen a death count.
595 BirthCountMap birth_counts;
596 ThreadData::SnapshotAllExecutedTasks(process_data_phase, &birth_counts);
597
598 // Add births that are still active -- i.e. objects that have tallied a birth,
599 // but have not yet tallied a matching death, and hence must be either
600 // running, queued up, or being held in limbo for future posting.
601 for (const auto& birth_count : birth_counts) {
602 if (birth_count.second > 0) {
603 process_data_phase->tasks.push_back(TaskSnapshot(
604 *birth_count.first, DeathData(birth_count.second), "Still_Alive"));
605 }
606 }
607 }
608
609 void ThreadData::SnapshotExecutedTasks(
610 ProcessDataPhaseSnapshot* process_data_phase,
611 BirthCountMap* birth_counts) {
604 // Get copy of data, so that the data will not change during the iterations 612 // Get copy of data, so that the data will not change during the iterations
605 // and processing. 613 // and processing.
606 ThreadData::BirthMap birth_map; 614 ThreadData::BirthMap birth_map;
607 ThreadData::DeathMap death_map; 615 ThreadData::DeathMap death_map;
608 ThreadData::ParentChildSet parent_child_set; 616 ThreadData::ParentChildSet parent_child_set;
609 SnapshotMaps(&birth_map, &death_map, &parent_child_set); 617 SnapshotMaps(&birth_map, &death_map, &parent_child_set);
610 618
611 for (ThreadData::DeathMap::const_iterator it = death_map.begin(); 619 for (const auto& death : death_map) {
612 it != death_map.end(); ++it) { 620 process_data_phase->tasks.push_back(
613 process_data->tasks.push_back( 621 TaskSnapshot(*death.first, death.second, thread_name()));
614 TaskSnapshot(*it->first, it->second, thread_name())); 622 (*birth_counts)[death.first] -= death.first->birth_count();
615 (*birth_counts)[it->first] -= it->first->birth_count();
616 } 623 }
617 624
618 for (ThreadData::BirthMap::const_iterator it = birth_map.begin(); 625 for (const auto& birth : birth_map) {
619 it != birth_map.end(); ++it) { 626 (*birth_counts)[birth.second] += birth.second->birth_count();
620 (*birth_counts)[it->second] += it->second->birth_count();
621 } 627 }
622 628
623 if (!kTrackParentChildLinks) 629 if (!kTrackParentChildLinks)
624 return; 630 return;
625 631
626 for (ThreadData::ParentChildSet::const_iterator it = parent_child_set.begin(); 632 for (const auto& parent_child : parent_child_set) {
627 it != parent_child_set.end(); ++it) { 633 process_data_phase->descendants.push_back(
628 process_data->descendants.push_back(ParentChildPairSnapshot(*it)); 634 ParentChildPairSnapshot(parent_child));
629 } 635 }
630 } 636 }
631 637
632 // This may be called from another thread. 638 // This may be called from another thread.
633 void ThreadData::SnapshotMaps(BirthMap* birth_map, 639 void ThreadData::SnapshotMaps(BirthMap* birth_map,
634 DeathMap* death_map, 640 DeathMap* death_map,
635 ParentChildSet* parent_child_set) { 641 ParentChildSet* parent_child_set) {
636 base::AutoLock lock(map_lock_); 642 base::AutoLock lock(map_lock_);
637 for (BirthMap::const_iterator it = birth_map_.begin(); 643 for (const auto& birth : birth_map_)
638 it != birth_map_.end(); ++it) 644 (*birth_map)[birth.first] = birth.second;
639 (*birth_map)[it->first] = it->second; 645 for (const auto& death : death_map_)
640 for (DeathMap::iterator it = death_map_.begin(); 646 (*death_map)[death.first] = death.second;
641 it != death_map_.end(); ++it) {
642 (*death_map)[it->first] = it->second;
643 }
644 647
645 if (!kTrackParentChildLinks) 648 if (!kTrackParentChildLinks)
646 return; 649 return;
647 650
648 for (ParentChildSet::iterator it = parent_child_set_.begin(); 651 for (const auto& parent_child : parent_child_set_)
649 it != parent_child_set_.end(); ++it) 652 parent_child_set->insert(parent_child);
650 parent_child_set->insert(*it);
651 } 653 }
652 654
653 static void OptionallyInitializeAlternateTimer() { 655 static void OptionallyInitializeAlternateTimer() {
654 NowFunction* alternate_time_source = GetAlternateTimeSource(); 656 NowFunction* alternate_time_source = GetAlternateTimeSource();
655 if (alternate_time_source) 657 if (alternate_time_source)
656 ThreadData::SetAlternateTimeSource(alternate_time_source); 658 ThreadData::SetAlternateTimeSource(alternate_time_source);
657 } 659 }
658 660
659 bool ThreadData::Initialize() { 661 bool ThreadData::Initialize() {
660 if (!kTrackAllTaskObjects) 662 if (!kTrackAllTaskObjects)
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 ParentChildPairSnapshot::ParentChildPairSnapshot( 954 ParentChildPairSnapshot::ParentChildPairSnapshot(
953 const ThreadData::ParentChildPair& parent_child) 955 const ThreadData::ParentChildPair& parent_child)
954 : parent(*parent_child.first), 956 : parent(*parent_child.first),
955 child(*parent_child.second) { 957 child(*parent_child.second) {
956 } 958 }
957 959
958 ParentChildPairSnapshot::~ParentChildPairSnapshot() { 960 ParentChildPairSnapshot::~ParentChildPairSnapshot() {
959 } 961 }
960 962
961 //------------------------------------------------------------------------------ 963 //------------------------------------------------------------------------------
962 // ProcessDataSnapshot 964 // ProcessDataPhaseSnapshot
965
966 ProcessDataPhaseSnapshot::ProcessDataPhaseSnapshot() {
967 }
968
969 ProcessDataPhaseSnapshot::~ProcessDataPhaseSnapshot() {
970 }
971
972 //------------------------------------------------------------------------------
973 // ProcessDataPhaseSnapshot
963 974
964 ProcessDataSnapshot::ProcessDataSnapshot() 975 ProcessDataSnapshot::ProcessDataSnapshot()
965 #if !defined(OS_NACL) 976 #if !defined(OS_NACL)
966 : process_id(base::GetCurrentProcId()) { 977 : process_id(base::GetCurrentProcId()) {
967 #else 978 #else
968 : process_id(0) { 979 : process_id(base::kNullProcessId) {
969 #endif 980 #endif
970 } 981 }
971 982
972 ProcessDataSnapshot::~ProcessDataSnapshot() { 983 ProcessDataSnapshot::~ProcessDataSnapshot() {
973 } 984 }
974 985
975 } // namespace tracked_objects 986 } // namespace tracked_objects
OLDNEW
« no previous file with comments | « base/tracked_objects.h ('k') | base/tracked_objects_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698