| 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/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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 // but that should be inconsequentially likely). We ignore the fact that we | 161 // but that should be inconsequentially likely). We ignore the fact that we |
| 162 // correlated our selection of a sample to the run and queue times (i.e., we | 162 // correlated our selection of a sample to the run and queue times (i.e., we |
| 163 // used them to generate random_number). | 163 // used them to generate random_number). |
| 164 CHECK_GT(sample_probability_count, 0); | 164 CHECK_GT(sample_probability_count, 0); |
| 165 if (0 == (random_number % sample_probability_count)) { | 165 if (0 == (random_number % sample_probability_count)) { |
| 166 queue_duration_sample_ = queue_duration; | 166 queue_duration_sample_ = queue_duration; |
| 167 run_duration_sample_ = run_duration; | 167 run_duration_sample_ = run_duration; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 int DeathData::count() const { return count_; } | |
| 172 | |
| 173 int32 DeathData::run_duration_sum() const { return run_duration_sum_; } | |
| 174 | |
| 175 int32 DeathData::run_duration_max() const { return run_duration_max_; } | |
| 176 | |
| 177 int32 DeathData::run_duration_sample() const { | |
| 178 return run_duration_sample_; | |
| 179 } | |
| 180 | |
| 181 int32 DeathData::queue_duration_sum() const { | |
| 182 return queue_duration_sum_; | |
| 183 } | |
| 184 | |
| 185 int32 DeathData::queue_duration_max() const { | |
| 186 return queue_duration_max_; | |
| 187 } | |
| 188 | |
| 189 int32 DeathData::queue_duration_sample() const { | |
| 190 return queue_duration_sample_; | |
| 191 } | |
| 192 | |
| 193 const DeathDataPhaseSnapshot* DeathData::last_phase_snapshot() const { | |
| 194 return last_phase_snapshot_; | |
| 195 } | |
| 196 | |
| 197 void DeathData::OnProfilingPhaseCompleted(int profiling_phase) { | 171 void DeathData::OnProfilingPhaseCompleted(int profiling_phase) { |
| 198 // Snapshotting and storing current state. | 172 // Snapshotting and storing current state. |
| 199 last_phase_snapshot_ = new DeathDataPhaseSnapshot( | 173 last_phase_snapshot_ = new DeathDataPhaseSnapshot( |
| 200 profiling_phase, count_, run_duration_sum_, run_duration_max_, | 174 profiling_phase, count_, run_duration_sum_, run_duration_max_, |
| 201 run_duration_sample_, queue_duration_sum_, queue_duration_max_, | 175 run_duration_sample_, queue_duration_sum_, queue_duration_max_, |
| 202 queue_duration_sample_, last_phase_snapshot_); | 176 queue_duration_sample_, last_phase_snapshot_); |
| 203 | 177 |
| 204 // Not touching fields for which a delta can be computed by comparing with a | 178 // Not touching fields for which a delta can be computed by comparing with a |
| 205 // snapshot from the previous phase. Resetting other fields. Sample values | 179 // snapshot from the previous phase. Resetting other fields. Sample values |
| 206 // will be reset upon next death recording because sample_probability_count_ | 180 // will be reset upon next death recording because sample_probability_count_ |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 // static | 355 // static |
| 382 ThreadData* ThreadData::first() { | 356 ThreadData* ThreadData::first() { |
| 383 base::AutoLock lock(*list_lock_.Pointer()); | 357 base::AutoLock lock(*list_lock_.Pointer()); |
| 384 return all_thread_data_list_head_; | 358 return all_thread_data_list_head_; |
| 385 } | 359 } |
| 386 | 360 |
| 387 ThreadData* ThreadData::next() const { return next_; } | 361 ThreadData* ThreadData::next() const { return next_; } |
| 388 | 362 |
| 389 // static | 363 // static |
| 390 void ThreadData::InitializeThreadContext(const std::string& suggested_name) { | 364 void ThreadData::InitializeThreadContext(const std::string& suggested_name) { |
| 391 if (!Initialize()) // Always initialize if needed. | 365 Initialize(); |
| 392 return; | |
| 393 ThreadData* current_thread_data = | 366 ThreadData* current_thread_data = |
| 394 reinterpret_cast<ThreadData*>(tls_index_.Get()); | 367 reinterpret_cast<ThreadData*>(tls_index_.Get()); |
| 395 if (current_thread_data) | 368 if (current_thread_data) |
| 396 return; // Browser tests instigate this. | 369 return; // Browser tests instigate this. |
| 397 current_thread_data = new ThreadData(suggested_name); | 370 current_thread_data = new ThreadData(suggested_name); |
| 398 tls_index_.Set(current_thread_data); | 371 tls_index_.Set(current_thread_data); |
| 399 } | 372 } |
| 400 | 373 |
| 401 // static | 374 // static |
| 402 ThreadData* ThreadData::Get() { | 375 ThreadData* ThreadData::Get() { |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 death.second.OnProfilingPhaseCompleted(profiling_phase); | 684 death.second.OnProfilingPhaseCompleted(profiling_phase); |
| 712 } | 685 } |
| 713 } | 686 } |
| 714 | 687 |
| 715 static void OptionallyInitializeAlternateTimer() { | 688 static void OptionallyInitializeAlternateTimer() { |
| 716 NowFunction* alternate_time_source = GetAlternateTimeSource(); | 689 NowFunction* alternate_time_source = GetAlternateTimeSource(); |
| 717 if (alternate_time_source) | 690 if (alternate_time_source) |
| 718 ThreadData::SetAlternateTimeSource(alternate_time_source); | 691 ThreadData::SetAlternateTimeSource(alternate_time_source); |
| 719 } | 692 } |
| 720 | 693 |
| 721 bool ThreadData::Initialize() { | 694 void ThreadData::Initialize() { |
| 722 if (status_ >= DEACTIVATED) | 695 if (status_ >= DEACTIVATED) |
| 723 return true; // Someone else did the initialization. | 696 return; // Someone else did the initialization. |
| 724 // Due to racy lazy initialization in tests, we'll need to recheck status_ | 697 // Due to racy lazy initialization in tests, we'll need to recheck status_ |
| 725 // after we acquire the lock. | 698 // after we acquire the lock. |
| 726 | 699 |
| 727 // Ensure that we don't double initialize tls. We are called when single | 700 // Ensure that we don't double initialize tls. We are called when single |
| 728 // threaded in the product, but some tests may be racy and lazy about our | 701 // threaded in the product, but some tests may be racy and lazy about our |
| 729 // initialization. | 702 // initialization. |
| 730 base::AutoLock lock(*list_lock_.Pointer()); | 703 base::AutoLock lock(*list_lock_.Pointer()); |
| 731 if (status_ >= DEACTIVATED) | 704 if (status_ >= DEACTIVATED) |
| 732 return true; // Someone raced in here and beat us. | 705 return; // Someone raced in here and beat us. |
| 733 | 706 |
| 734 // Put an alternate timer in place if the environment calls for it, such as | 707 // Put an alternate timer in place if the environment calls for it, such as |
| 735 // for tracking TCMalloc allocations. This insertion is idempotent, so we | 708 // for tracking TCMalloc allocations. This insertion is idempotent, so we |
| 736 // don't mind if there is a race, and we'd prefer not to be in a lock while | 709 // don't mind if there is a race, and we'd prefer not to be in a lock while |
| 737 // doing this work. | 710 // doing this work. |
| 738 if (kAllowAlternateTimeSourceHandling) | 711 if (kAllowAlternateTimeSourceHandling) |
| 739 OptionallyInitializeAlternateTimer(); | 712 OptionallyInitializeAlternateTimer(); |
| 740 | 713 |
| 741 // Perform the "real" TLS initialization now, and leave it intact through | 714 // Perform the "real" TLS initialization now, and leave it intact through |
| 742 // process termination. | 715 // process termination. |
| 743 if (!tls_index_.initialized()) { // Testing may have initialized this. | 716 if (!tls_index_.initialized()) { // Testing may have initialized this. |
| 744 DCHECK_EQ(status_, UNINITIALIZED); | 717 DCHECK_EQ(status_, UNINITIALIZED); |
| 745 tls_index_.Initialize(&ThreadData::OnThreadTermination); | 718 tls_index_.Initialize(&ThreadData::OnThreadTermination); |
| 746 if (!tls_index_.initialized()) | 719 DCHECK(tls_index_.initialized()); |
| 747 return false; | |
| 748 } else { | 720 } else { |
| 749 // TLS was initialzed for us earlier. | 721 // TLS was initialzed for us earlier. |
| 750 DCHECK_EQ(status_, DORMANT_DURING_TESTS); | 722 DCHECK_EQ(status_, DORMANT_DURING_TESTS); |
| 751 } | 723 } |
| 752 | 724 |
| 753 // Incarnation counter is only significant to testing, as it otherwise will | 725 // Incarnation counter is only significant to testing, as it otherwise will |
| 754 // never again change in this process. | 726 // never again change in this process. |
| 755 ++incarnation_counter_; | 727 ++incarnation_counter_; |
| 756 | 728 |
| 757 // The lock is not critical for setting status_, but it doesn't hurt. It also | 729 // The lock is not critical for setting status_, but it doesn't hurt. It also |
| 758 // ensures that if we have a racy initialization, that we'll bail as soon as | 730 // ensures that if we have a racy initialization, that we'll bail as soon as |
| 759 // we get the lock earlier in this method. | 731 // we get the lock earlier in this method. |
| 760 status_ = kInitialStartupState; | 732 status_ = kInitialStartupState; |
| 761 DCHECK(status_ != UNINITIALIZED); | 733 DCHECK(status_ != UNINITIALIZED); |
| 762 return true; | |
| 763 } | 734 } |
| 764 | 735 |
| 765 // static | 736 // static |
| 766 bool ThreadData::InitializeAndSetTrackingStatus(Status status) { | 737 void ThreadData::InitializeAndSetTrackingStatus(Status status) { |
| 767 DCHECK_GE(status, DEACTIVATED); | 738 DCHECK_GE(status, DEACTIVATED); |
| 768 DCHECK_LE(status, PROFILING_ACTIVE); | 739 DCHECK_LE(status, PROFILING_ACTIVE); |
| 769 | 740 |
| 770 if (!Initialize()) // No-op if already initialized. | 741 Initialize(); // No-op if already initialized. |
| 771 return false; // Not compiled in. | |
| 772 | 742 |
| 773 if (status > DEACTIVATED) | 743 if (status > DEACTIVATED) |
| 774 status = PROFILING_ACTIVE; | 744 status = PROFILING_ACTIVE; |
| 775 status_ = status; | 745 status_ = status; |
| 776 return true; | |
| 777 } | 746 } |
| 778 | 747 |
| 779 // static | 748 // static |
| 780 ThreadData::Status ThreadData::status() { | 749 ThreadData::Status ThreadData::status() { |
| 781 return status_; | 750 return status_; |
| 782 } | 751 } |
| 783 | 752 |
| 784 // static | 753 // static |
| 785 bool ThreadData::TrackingStatus() { | 754 bool ThreadData::TrackingStatus() { |
| 786 return status_ > DEACTIVATED; | 755 return status_ > DEACTIVATED; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 // now. | 789 // now. |
| 821 CHECK_GT(cleanup_count_, major_threads_shutdown_count); | 790 CHECK_GT(cleanup_count_, major_threads_shutdown_count); |
| 822 #endif | 791 #endif |
| 823 } | 792 } |
| 824 | 793 |
| 825 // static | 794 // static |
| 826 void ThreadData::ShutdownSingleThreadedCleanup(bool leak) { | 795 void ThreadData::ShutdownSingleThreadedCleanup(bool leak) { |
| 827 // This is only called from test code, where we need to cleanup so that | 796 // This is only called from test code, where we need to cleanup so that |
| 828 // additional tests can be run. | 797 // additional tests can be run. |
| 829 // We must be single threaded... but be careful anyway. | 798 // We must be single threaded... but be careful anyway. |
| 830 if (!InitializeAndSetTrackingStatus(DEACTIVATED)) | 799 InitializeAndSetTrackingStatus(DEACTIVATED); |
| 831 return; | 800 |
| 832 ThreadData* thread_data_list; | 801 ThreadData* thread_data_list; |
| 833 { | 802 { |
| 834 base::AutoLock lock(*list_lock_.Pointer()); | 803 base::AutoLock lock(*list_lock_.Pointer()); |
| 835 thread_data_list = all_thread_data_list_head_; | 804 thread_data_list = all_thread_data_list_head_; |
| 836 all_thread_data_list_head_ = NULL; | 805 all_thread_data_list_head_ = NULL; |
| 837 ++incarnation_counter_; | 806 ++incarnation_counter_; |
| 838 // To be clean, break apart the retired worker list (though we leak them). | 807 // To be clean, break apart the retired worker list (though we leak them). |
| 839 while (first_retired_worker_) { | 808 while (first_retired_worker_) { |
| 840 ThreadData* worker = first_retired_worker_; | 809 ThreadData* worker = first_retired_worker_; |
| 841 CHECK_GT(worker->worker_thread_number_, 0); | 810 CHECK_GT(worker->worker_thread_number_, 0); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 : process_id(base::GetCurrentProcId()) { | 998 : process_id(base::GetCurrentProcId()) { |
| 1030 #else | 999 #else |
| 1031 : process_id(base::kNullProcessId) { | 1000 : process_id(base::kNullProcessId) { |
| 1032 #endif | 1001 #endif |
| 1033 } | 1002 } |
| 1034 | 1003 |
| 1035 ProcessDataSnapshot::~ProcessDataSnapshot() { | 1004 ProcessDataSnapshot::~ProcessDataSnapshot() { |
| 1036 } | 1005 } |
| 1037 | 1006 |
| 1038 } // namespace tracked_objects | 1007 } // namespace tracked_objects |
| OLD | NEW |