Chromium Code Reviews| 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/base_switches.h" | 9 #include "base/base_switches.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 707 // Not thread-safe. Once the ThreadMain has been called, this can no longer | 707 // Not thread-safe. Once the ThreadMain has been called, this can no longer |
| 708 // be called. | 708 // be called. |
| 709 void RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD* bucket, | 709 void RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD* bucket, |
| 710 const char* const name, | 710 const char* const name, |
| 711 TraceSampleCallback callback); | 711 TraceSampleCallback callback); |
| 712 // Splits a combined "category\0name" into the two component parts. | 712 // Splits a combined "category\0name" into the two component parts. |
| 713 static void ExtractCategoryAndName(const char* combined, | 713 static void ExtractCategoryAndName(const char* combined, |
| 714 const char** category, | 714 const char** category, |
| 715 const char** name); | 715 const char** name); |
| 716 std::vector<TraceBucketData> sample_buckets_; | 716 std::vector<TraceBucketData> sample_buckets_; |
| 717 Lock lock_; | |
| 717 bool thread_running_; | 718 bool thread_running_; |
| 718 scoped_ptr<CancellationFlag> cancellation_flag_; | 719 scoped_ptr<CancellationFlag> cancellation_flag_; |
| 719 scoped_ptr<WaitableEvent> waitable_event_for_testing_; | 720 scoped_ptr<WaitableEvent> waitable_event_for_testing_; |
| 720 }; | 721 }; |
| 721 | 722 |
| 722 | 723 |
| 723 TraceSamplingThread::TraceSamplingThread() | 724 TraceSamplingThread::TraceSamplingThread() |
| 724 : thread_running_(false) { | 725 : thread_running_(false) { |
| 726 AutoLock lock(lock_); | |
| 725 cancellation_flag_.reset(new CancellationFlag); | 727 cancellation_flag_.reset(new CancellationFlag); |
| 726 } | 728 } |
| 727 | 729 |
| 728 TraceSamplingThread::~TraceSamplingThread() { | 730 TraceSamplingThread::~TraceSamplingThread() { |
| 729 } | 731 } |
| 730 | 732 |
| 731 void TraceSamplingThread::ThreadMain() { | 733 void TraceSamplingThread::ThreadMain() { |
| 732 PlatformThread::SetName("Sampling Thread"); | 734 PlatformThread::SetName("Sampling Thread"); |
| 733 thread_running_ = true; | 735 thread_running_ = true; |
| 734 const int kSamplingFrequencyMicroseconds = 1000; | 736 const int kSamplingFrequencyMicroseconds = 1000; |
| 735 while (!cancellation_flag_->IsSet()) { | 737 while (true) { |
| 736 PlatformThread::Sleep( | 738 PlatformThread::Sleep( |
| 737 TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds)); | 739 TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds)); |
| 738 GetSamples(); | 740 GetSamples(); |
| 741 | |
| 742 AutoLock lock(lock_); | |
| 743 if (cancellation_flag_->IsSet()) | |
| 744 break; | |
| 739 if (waitable_event_for_testing_.get()) | 745 if (waitable_event_for_testing_.get()) |
| 740 waitable_event_for_testing_->Signal(); | 746 waitable_event_for_testing_->Signal(); |
| 741 } | 747 } |
| 742 } | 748 } |
| 743 | 749 |
| 744 // static | 750 // static |
| 745 void TraceSamplingThread::DefaultSamplingCallback( | 751 void TraceSamplingThread::DefaultSamplingCallback( |
| 746 TraceBucketData* bucket_data) { | 752 TraceBucketData* bucket_data) { |
| 747 TRACE_EVENT_API_ATOMIC_WORD category_and_name = | 753 TRACE_EVENT_API_ATOMIC_WORD category_and_name = |
| 748 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); | 754 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); |
| 749 if (!category_and_name) | 755 if (!category_and_name) |
| 750 return; | 756 return; |
| 751 const char* const combined = | 757 const char* const combined = |
| 752 reinterpret_cast<const char* const>(category_and_name); | 758 reinterpret_cast<const char* const>(category_and_name); |
| 753 const char* category_group; | 759 const char* category_group; |
| 754 const char* name; | 760 const char* name; |
| 755 ExtractCategoryAndName(combined, &category_group, &name); | 761 ExtractCategoryAndName(combined, &category_group, &name); |
| 756 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, | 762 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, |
| 757 TraceLog::GetCategoryGroupEnabled(category_group), | 763 TraceLog::GetCategoryGroupEnabled(category_group), |
| 758 name, 0, 0, NULL, NULL, NULL, NULL, 0); | 764 name, 0, 0, NULL, NULL, NULL, NULL, 0); |
| 759 } | 765 } |
| 760 | 766 |
| 761 void TraceSamplingThread::GetSamples() { | 767 void TraceSamplingThread::GetSamples() { |
|
dsinclair
2013/10/09 13:21:07
Do these other methods need to be locked as well?
haraken
2013/10/09 13:46:20
Yeah, the lock should also protect |sample_buckets
haraken
2013/10/10 01:20:49
Fixed.
| |
| 762 for (size_t i = 0; i < sample_buckets_.size(); ++i) { | 768 for (size_t i = 0; i < sample_buckets_.size(); ++i) { |
| 763 TraceBucketData* bucket_data = &sample_buckets_[i]; | 769 TraceBucketData* bucket_data = &sample_buckets_[i]; |
| 764 bucket_data->callback.Run(bucket_data); | 770 bucket_data->callback.Run(bucket_data); |
| 765 } | 771 } |
| 766 } | 772 } |
| 767 | 773 |
| 768 void TraceSamplingThread::RegisterSampleBucket( | 774 void TraceSamplingThread::RegisterSampleBucket( |
| 769 TRACE_EVENT_API_ATOMIC_WORD* bucket, | 775 TRACE_EVENT_API_ATOMIC_WORD* bucket, |
| 770 const char* const name, | 776 const char* const name, |
| 771 TraceSampleCallback callback) { | 777 TraceSampleCallback callback) { |
| 772 DCHECK(!thread_running_); | 778 DCHECK(!thread_running_); |
| 773 sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); | 779 sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); |
| 774 } | 780 } |
| 775 | 781 |
| 776 // static | 782 // static |
| 777 void TraceSamplingThread::ExtractCategoryAndName(const char* combined, | 783 void TraceSamplingThread::ExtractCategoryAndName(const char* combined, |
| 778 const char** category, | 784 const char** category, |
| 779 const char** name) { | 785 const char** name) { |
| 780 *category = combined; | 786 *category = combined; |
| 781 *name = &combined[strlen(combined) + 1]; | 787 *name = &combined[strlen(combined) + 1]; |
| 782 } | 788 } |
| 783 | 789 |
| 784 void TraceSamplingThread::Stop() { | 790 void TraceSamplingThread::Stop() { |
| 791 AutoLock lock(lock_); | |
| 785 cancellation_flag_->Set(); | 792 cancellation_flag_->Set(); |
| 786 } | 793 } |
| 787 | 794 |
| 788 void TraceSamplingThread::InstallWaitableEventForSamplingTesting( | 795 void TraceSamplingThread::InstallWaitableEventForSamplingTesting( |
| 789 WaitableEvent* waitable_event) { | 796 WaitableEvent* waitable_event) { |
| 797 AutoLock lock(lock_); | |
| 790 waitable_event_for_testing_.reset(waitable_event); | 798 waitable_event_for_testing_.reset(waitable_event); |
| 791 } | 799 } |
| 792 | 800 |
| 793 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, | 801 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, |
| 794 const char* name, | 802 const char* name, |
| 795 TraceSampleCallback callback) | 803 TraceSampleCallback callback) |
| 796 : bucket(bucket), | 804 : bucket(bucket), |
| 797 bucket_name(name), | 805 bucket_name(name), |
| 798 callback(callback) { | 806 callback(callback) { |
| 799 } | 807 } |
| (...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2068 0, // num_args | 2076 0, // num_args |
| 2069 NULL, // arg_names | 2077 NULL, // arg_names |
| 2070 NULL, // arg_types | 2078 NULL, // arg_types |
| 2071 NULL, // arg_values | 2079 NULL, // arg_values |
| 2072 NULL, // convertable values | 2080 NULL, // convertable values |
| 2073 TRACE_EVENT_FLAG_NONE); // flags | 2081 TRACE_EVENT_FLAG_NONE); // flags |
| 2074 } | 2082 } |
| 2075 } | 2083 } |
| 2076 | 2084 |
| 2077 } // namespace trace_event_internal | 2085 } // namespace trace_event_internal |
| OLD | NEW |