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

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: Only "API" Created 5 years, 9 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
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::GetProcessDataSnapshot(
394 // Add births that have run to completion to |collected_data|. 394 ProcessDataSnapshot* process_data_snapshot) {
395 // |birth_counts| tracks the total number of births recorded at each location 395 ThreadData::Snapshot(
396 // for which we have not seen a death count. 396 &process_data_snapshot->phased_process_data_snapshots[0]);
Ilya Sherman 2015/03/10 00:48:10 What guarantees that the vector is non-empty?
vadimt 2015/03/13 23:18:00 It's a map, and indexing it creates an entry.
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 } 397 }
411 398
412 Births* ThreadData::TallyABirth(const Location& location) { 399 Births* ThreadData::TallyABirth(const Location& location) {
413 BirthMap::iterator it = birth_map_.find(location); 400 BirthMap::iterator it = birth_map_.find(location);
414 Births* child; 401 Births* child;
415 if (it != birth_map_.end()) { 402 if (it != birth_map_.end()) {
416 child = it->second; 403 child = it->second;
417 child->RecordBirth(); 404 child->RecordBirth();
418 } else { 405 } else {
419 child = new Births(location, *this); // Leak this. 406 child = new Births(location, *this); // Leak this.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 558
572 ThreadData* current_thread_data = stopwatch.GetThreadData(); 559 ThreadData* current_thread_data = stopwatch.GetThreadData();
573 if (!current_thread_data) 560 if (!current_thread_data)
574 return; 561 return;
575 562
576 int32 queue_duration = 0; 563 int32 queue_duration = 0;
577 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch); 564 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch);
578 } 565 }
579 566
580 // static 567 // static
581 void ThreadData::SnapshotAllExecutedTasks(ProcessDataSnapshot* process_data, 568 void ThreadData::SnapshotAllExecutedTasks(
582 BirthCountMap* birth_counts) { 569 ProcessDataPhaseSnapshot* process_data_phase,
570 BirthCountMap* birth_counts) {
583 if (!kTrackAllTaskObjects) 571 if (!kTrackAllTaskObjects)
584 return; // Not compiled in. 572 return; // Not compiled in.
585 573
586 // Get an unchanging copy of a ThreadData list. 574 // Get an unchanging copy of a ThreadData list.
587 ThreadData* my_list = ThreadData::first(); 575 ThreadData* my_list = ThreadData::first();
588 576
589 // Gather data serially. 577 // Gather data serially.
590 // This hackish approach *can* get some slighly corrupt tallies, as we are 578 // 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 579 // 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 580 // 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 581 // sees any strangeness, they can always just run their stats gathering a
594 // second time. 582 // second time.
595 for (ThreadData* thread_data = my_list; 583 for (ThreadData* thread_data = my_list;
596 thread_data; 584 thread_data;
597 thread_data = thread_data->next()) { 585 thread_data = thread_data->next()) {
598 thread_data->SnapshotExecutedTasks(process_data, birth_counts); 586 thread_data->SnapshotExecutedTasks(process_data_phase, birth_counts);
599 } 587 }
600 } 588 }
601 589
602 void ThreadData::SnapshotExecutedTasks(ProcessDataSnapshot* process_data, 590 // static
603 BirthCountMap* birth_counts) { 591 void ThreadData::Snapshot(ProcessDataPhaseSnapshot* process_data_phase) {
Ilya Sherman 2015/03/10 00:48:10 nit: I'd prefer to give this method a new name, an
vadimt 2015/03/13 23:18:00 Done.
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& i : birth_counts) {
Ilya Sherman 2015/03/10 00:48:10 nit: Please use a more semantically contentful nam
vadimt 2015/03/13 23:18:00 Done.
602 if (i.second > 0) {
603 process_data_phase->tasks.push_back(
604 TaskSnapshot(*i.first, DeathData(i.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& i : death_map) {
Ilya Sherman 2015/03/10 00:48:10 Same comment applies here, and for all other loops
vadimt 2015/03/13 23:18:01 Done.
612 it != death_map.end(); ++it) { 620 process_data_phase->tasks.push_back(
613 process_data->tasks.push_back( 621 TaskSnapshot(*i.first, i.second, thread_name()));
614 TaskSnapshot(*it->first, it->second, thread_name())); 622 (*birth_counts)[i.first] -= i.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& i : birth_map) {
619 it != birth_map.end(); ++it) { 626 (*birth_counts)[i.second] += i.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& i : parent_child_set) {
627 it != parent_child_set.end(); ++it) { 633 process_data_phase->descendants.push_back(ParentChildPairSnapshot(i));
628 process_data->descendants.push_back(ParentChildPairSnapshot(*it));
629 } 634 }
630 } 635 }
631 636
632 // This may be called from another thread. 637 // This may be called from another thread.
633 void ThreadData::SnapshotMaps(BirthMap* birth_map, 638 void ThreadData::SnapshotMaps(BirthMap* birth_map,
634 DeathMap* death_map, 639 DeathMap* death_map,
635 ParentChildSet* parent_child_set) { 640 ParentChildSet* parent_child_set) {
636 base::AutoLock lock(map_lock_); 641 base::AutoLock lock(map_lock_);
637 for (BirthMap::const_iterator it = birth_map_.begin(); 642 for (const auto& i : birth_map_)
638 it != birth_map_.end(); ++it) 643 (*birth_map)[i.first] = i.second;
639 (*birth_map)[it->first] = it->second; 644 for (auto& i : death_map_)
640 for (DeathMap::iterator it = death_map_.begin(); 645 (*death_map)[i.first] = i.second;
641 it != death_map_.end(); ++it) {
642 (*death_map)[it->first] = it->second;
643 }
644 646
645 if (!kTrackParentChildLinks) 647 if (!kTrackParentChildLinks)
646 return; 648 return;
647 649
648 for (ParentChildSet::iterator it = parent_child_set_.begin(); 650 for (const auto& i : parent_child_set_)
649 it != parent_child_set_.end(); ++it) 651 parent_child_set->insert(i);
Ilya Sherman 2015/03/10 00:48:10 I'd prefer to see the C++11-ization of the for loo
vadimt 2015/03/13 23:18:00 At some point, I've done C++11-ization by asvitkin
650 parent_child_set->insert(*it);
651 } 652 }
652 653
653 static void OptionallyInitializeAlternateTimer() { 654 static void OptionallyInitializeAlternateTimer() {
654 NowFunction* alternate_time_source = GetAlternateTimeSource(); 655 NowFunction* alternate_time_source = GetAlternateTimeSource();
655 if (alternate_time_source) 656 if (alternate_time_source)
656 ThreadData::SetAlternateTimeSource(alternate_time_source); 657 ThreadData::SetAlternateTimeSource(alternate_time_source);
657 } 658 }
658 659
659 bool ThreadData::Initialize() { 660 bool ThreadData::Initialize() {
660 if (!kTrackAllTaskObjects) 661 if (!kTrackAllTaskObjects)
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 ParentChildPairSnapshot::ParentChildPairSnapshot( 953 ParentChildPairSnapshot::ParentChildPairSnapshot(
953 const ThreadData::ParentChildPair& parent_child) 954 const ThreadData::ParentChildPair& parent_child)
954 : parent(*parent_child.first), 955 : parent(*parent_child.first),
955 child(*parent_child.second) { 956 child(*parent_child.second) {
956 } 957 }
957 958
958 ParentChildPairSnapshot::~ParentChildPairSnapshot() { 959 ParentChildPairSnapshot::~ParentChildPairSnapshot() {
959 } 960 }
960 961
961 //------------------------------------------------------------------------------ 962 //------------------------------------------------------------------------------
962 // ProcessDataSnapshot 963 // ProcessDataPhaseSnapshot
964
965 ProcessDataPhaseSnapshot::ProcessDataPhaseSnapshot() {
966 }
967
968 ProcessDataPhaseSnapshot::~ProcessDataPhaseSnapshot() {
969 }
970
971 //------------------------------------------------------------------------------
972 // ProcessDataPhaseSnapshot
963 973
964 ProcessDataSnapshot::ProcessDataSnapshot() 974 ProcessDataSnapshot::ProcessDataSnapshot()
965 #if !defined(OS_NACL) 975 #if !defined(OS_NACL)
966 : process_id(base::GetCurrentProcId()) { 976 : process_id(base::GetCurrentProcId()) {
967 #else 977 #else
968 : process_id(0) { 978 : process_id(0) {
969 #endif 979 #endif
970 } 980 }
971 981
972 ProcessDataSnapshot::~ProcessDataSnapshot() { 982 ProcessDataSnapshot::~ProcessDataSnapshot() {
973 } 983 }
974 984
975 } // namespace tracked_objects 985 } // namespace tracked_objects
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698