| 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 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 public: | 833 public: |
| 834 TraceSamplingThread(); | 834 TraceSamplingThread(); |
| 835 virtual ~TraceSamplingThread(); | 835 virtual ~TraceSamplingThread(); |
| 836 | 836 |
| 837 // Implementation of PlatformThread::Delegate: | 837 // Implementation of PlatformThread::Delegate: |
| 838 virtual void ThreadMain() OVERRIDE; | 838 virtual void ThreadMain() OVERRIDE; |
| 839 | 839 |
| 840 static void DefaultSamplingCallback(TraceBucketData* bucekt_data); | 840 static void DefaultSamplingCallback(TraceBucketData* bucekt_data); |
| 841 | 841 |
| 842 void Stop(); | 842 void Stop(); |
| 843 void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event); | 843 void WaitSamplingEventForTesting(); |
| 844 | 844 |
| 845 private: | 845 private: |
| 846 friend class TraceLog; | 846 friend class TraceLog; |
| 847 | 847 |
| 848 void GetSamples(); | 848 void GetSamples(); |
| 849 // Not thread-safe. Once the ThreadMain has been called, this can no longer | 849 // Not thread-safe. Once the ThreadMain has been called, this can no longer |
| 850 // be called. | 850 // be called. |
| 851 void RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD* bucket, | 851 void RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD* bucket, |
| 852 const char* const name, | 852 const char* const name, |
| 853 TraceSampleCallback callback); | 853 TraceSampleCallback callback); |
| 854 // Splits a combined "category\0name" into the two component parts. | 854 // Splits a combined "category\0name" into the two component parts. |
| 855 static void ExtractCategoryAndName(const char* combined, | 855 static void ExtractCategoryAndName(const char* combined, |
| 856 const char** category, | 856 const char** category, |
| 857 const char** name); | 857 const char** name); |
| 858 std::vector<TraceBucketData> sample_buckets_; | 858 std::vector<TraceBucketData> sample_buckets_; |
| 859 bool thread_running_; | 859 bool thread_running_; |
| 860 scoped_ptr<CancellationFlag> cancellation_flag_; | 860 CancellationFlag cancellation_flag_; |
| 861 scoped_ptr<WaitableEvent> waitable_event_for_testing_; | 861 WaitableEvent waitable_event_for_testing_; |
| 862 }; | 862 }; |
| 863 | 863 |
| 864 | 864 |
| 865 TraceSamplingThread::TraceSamplingThread() | 865 TraceSamplingThread::TraceSamplingThread() |
| 866 : thread_running_(false) { | 866 : thread_running_(false), |
| 867 cancellation_flag_.reset(new CancellationFlag); | 867 waitable_event_for_testing_(false, false) { |
| 868 } | 868 } |
| 869 | 869 |
| 870 TraceSamplingThread::~TraceSamplingThread() { | 870 TraceSamplingThread::~TraceSamplingThread() { |
| 871 } | 871 } |
| 872 | 872 |
| 873 void TraceSamplingThread::ThreadMain() { | 873 void TraceSamplingThread::ThreadMain() { |
| 874 PlatformThread::SetName("Sampling Thread"); | 874 PlatformThread::SetName("Sampling Thread"); |
| 875 thread_running_ = true; | 875 thread_running_ = true; |
| 876 const int kSamplingFrequencyMicroseconds = 1000; | 876 const int kSamplingFrequencyMicroseconds = 1000; |
| 877 while (!cancellation_flag_->IsSet()) { | 877 while (!cancellation_flag_.IsSet()) { |
| 878 PlatformThread::Sleep( | 878 PlatformThread::Sleep( |
| 879 TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds)); | 879 TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds)); |
| 880 GetSamples(); | 880 GetSamples(); |
| 881 if (waitable_event_for_testing_.get()) | 881 waitable_event_for_testing_.Signal(); |
| 882 waitable_event_for_testing_->Signal(); | |
| 883 } | 882 } |
| 884 } | 883 } |
| 885 | 884 |
| 886 // static | 885 // static |
| 887 void TraceSamplingThread::DefaultSamplingCallback( | 886 void TraceSamplingThread::DefaultSamplingCallback( |
| 888 TraceBucketData* bucket_data) { | 887 TraceBucketData* bucket_data) { |
| 889 TRACE_EVENT_API_ATOMIC_WORD category_and_name = | 888 TRACE_EVENT_API_ATOMIC_WORD category_and_name = |
| 890 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); | 889 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); |
| 891 if (!category_and_name) | 890 if (!category_and_name) |
| 892 return; | 891 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 904 for (size_t i = 0; i < sample_buckets_.size(); ++i) { | 903 for (size_t i = 0; i < sample_buckets_.size(); ++i) { |
| 905 TraceBucketData* bucket_data = &sample_buckets_[i]; | 904 TraceBucketData* bucket_data = &sample_buckets_[i]; |
| 906 bucket_data->callback.Run(bucket_data); | 905 bucket_data->callback.Run(bucket_data); |
| 907 } | 906 } |
| 908 } | 907 } |
| 909 | 908 |
| 910 void TraceSamplingThread::RegisterSampleBucket( | 909 void TraceSamplingThread::RegisterSampleBucket( |
| 911 TRACE_EVENT_API_ATOMIC_WORD* bucket, | 910 TRACE_EVENT_API_ATOMIC_WORD* bucket, |
| 912 const char* const name, | 911 const char* const name, |
| 913 TraceSampleCallback callback) { | 912 TraceSampleCallback callback) { |
| 913 // Access to sample_buckets_ doesn't cause races with the sampling thread |
| 914 // that uses the sample_buckets_, because it is guaranteed that |
| 915 // RegisterSampleBucket is called before the sampling thread is created. |
| 914 DCHECK(!thread_running_); | 916 DCHECK(!thread_running_); |
| 915 sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); | 917 sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); |
| 916 } | 918 } |
| 917 | 919 |
| 918 // static | 920 // static |
| 919 void TraceSamplingThread::ExtractCategoryAndName(const char* combined, | 921 void TraceSamplingThread::ExtractCategoryAndName(const char* combined, |
| 920 const char** category, | 922 const char** category, |
| 921 const char** name) { | 923 const char** name) { |
| 922 *category = combined; | 924 *category = combined; |
| 923 *name = &combined[strlen(combined) + 1]; | 925 *name = &combined[strlen(combined) + 1]; |
| 924 } | 926 } |
| 925 | 927 |
| 926 void TraceSamplingThread::Stop() { | 928 void TraceSamplingThread::Stop() { |
| 927 cancellation_flag_->Set(); | 929 cancellation_flag_.Set(); |
| 928 } | 930 } |
| 929 | 931 |
| 930 void TraceSamplingThread::InstallWaitableEventForSamplingTesting( | 932 void TraceSamplingThread::WaitSamplingEventForTesting() { |
| 931 WaitableEvent* waitable_event) { | 933 waitable_event_for_testing_.Wait(); |
| 932 waitable_event_for_testing_.reset(waitable_event); | |
| 933 } | 934 } |
| 934 | 935 |
| 935 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, | 936 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, |
| 936 const char* name, | 937 const char* name, |
| 937 TraceSampleCallback callback) | 938 TraceSampleCallback callback) |
| 938 : bucket(bucket), | 939 : bucket(bucket), |
| 939 bucket_name(name), | 940 bucket_name(name), |
| 940 callback(callback) { | 941 callback(callback) { |
| 941 } | 942 } |
| 942 | 943 |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 it++) { | 1996 it++) { |
| 1996 if (it->second.empty()) | 1997 if (it->second.empty()) |
| 1997 continue; | 1998 continue; |
| 1998 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), | 1999 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), |
| 1999 it->first, | 2000 it->first, |
| 2000 "thread_name", "name", | 2001 "thread_name", "name", |
| 2001 it->second); | 2002 it->second); |
| 2002 } | 2003 } |
| 2003 } | 2004 } |
| 2004 | 2005 |
| 2005 void TraceLog::InstallWaitableEventForSamplingTesting( | 2006 void TraceLog::WaitSamplingEventForTesting() { |
| 2006 WaitableEvent* waitable_event) { | |
| 2007 if (!sampling_thread_) | 2007 if (!sampling_thread_) |
| 2008 return; | 2008 return; |
| 2009 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); | 2009 sampling_thread_->WaitSamplingEventForTesting(); |
| 2010 } | 2010 } |
| 2011 | 2011 |
| 2012 void TraceLog::DeleteForTesting() { | 2012 void TraceLog::DeleteForTesting() { |
| 2013 DeleteTraceLogForTesting::Delete(); | 2013 DeleteTraceLogForTesting::Delete(); |
| 2014 } | 2014 } |
| 2015 | 2015 |
| 2016 TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) { | 2016 TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) { |
| 2017 return GetEventByHandleInternal(handle, NULL); | 2017 return GetEventByHandleInternal(handle, NULL); |
| 2018 } | 2018 } |
| 2019 | 2019 |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 0, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE); | 2281 0, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE); |
| 2282 } | 2282 } |
| 2283 } | 2283 } |
| 2284 | 2284 |
| 2285 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2285 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2286 if (*category_group_enabled_) | 2286 if (*category_group_enabled_) |
| 2287 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(event_handle_); | 2287 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(event_handle_); |
| 2288 } | 2288 } |
| 2289 | 2289 |
| 2290 } // namespace trace_event_internal | 2290 } // namespace trace_event_internal |
| OLD | NEW |