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

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 26541005: Avoid threading races on TraceSamplingThread's members. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/valgrind/tsan_v2/suppressions.txt » ('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/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 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 void GetSamples(); 706 void GetSamples();
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 Lock lock_;
716 std::vector<TraceBucketData> sample_buckets_; 717 std::vector<TraceBucketData> sample_buckets_;
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() {
768 Lock lock_;
dsinclair 2013/10/10 01:22:48 I think you want AutoLock lock(lock_) ? (and below
haraken 2013/10/10 01:36:20 Sorry... fixed and verified compile.
762 for (size_t i = 0; i < sample_buckets_.size(); ++i) { 769 for (size_t i = 0; i < sample_buckets_.size(); ++i) {
763 TraceBucketData* bucket_data = &sample_buckets_[i]; 770 TraceBucketData* bucket_data = &sample_buckets_[i];
764 bucket_data->callback.Run(bucket_data); 771 bucket_data->callback.Run(bucket_data);
765 } 772 }
766 } 773 }
767 774
768 void TraceSamplingThread::RegisterSampleBucket( 775 void TraceSamplingThread::RegisterSampleBucket(
769 TRACE_EVENT_API_ATOMIC_WORD* bucket, 776 TRACE_EVENT_API_ATOMIC_WORD* bucket,
770 const char* const name, 777 const char* const name,
771 TraceSampleCallback callback) { 778 TraceSampleCallback callback) {
779 Lock lock_;
772 DCHECK(!thread_running_); 780 DCHECK(!thread_running_);
773 sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); 781 sample_buckets_.push_back(TraceBucketData(bucket, name, callback));
774 } 782 }
775 783
776 // static 784 // static
777 void TraceSamplingThread::ExtractCategoryAndName(const char* combined, 785 void TraceSamplingThread::ExtractCategoryAndName(const char* combined,
778 const char** category, 786 const char** category,
779 const char** name) { 787 const char** name) {
780 *category = combined; 788 *category = combined;
781 *name = &combined[strlen(combined) + 1]; 789 *name = &combined[strlen(combined) + 1];
782 } 790 }
783 791
784 void TraceSamplingThread::Stop() { 792 void TraceSamplingThread::Stop() {
793 AutoLock lock(lock_);
785 cancellation_flag_->Set(); 794 cancellation_flag_->Set();
786 } 795 }
787 796
788 void TraceSamplingThread::InstallWaitableEventForSamplingTesting( 797 void TraceSamplingThread::InstallWaitableEventForSamplingTesting(
789 WaitableEvent* waitable_event) { 798 WaitableEvent* waitable_event) {
799 AutoLock lock(lock_);
790 waitable_event_for_testing_.reset(waitable_event); 800 waitable_event_for_testing_.reset(waitable_event);
791 } 801 }
792 802
793 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, 803 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket,
794 const char* name, 804 const char* name,
795 TraceSampleCallback callback) 805 TraceSampleCallback callback)
796 : bucket(bucket), 806 : bucket(bucket),
797 bucket_name(name), 807 bucket_name(name),
798 callback(callback) { 808 callback(callback) {
799 } 809 }
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 0, // num_args 2078 0, // num_args
2069 NULL, // arg_names 2079 NULL, // arg_names
2070 NULL, // arg_types 2080 NULL, // arg_types
2071 NULL, // arg_values 2081 NULL, // arg_values
2072 NULL, // convertable values 2082 NULL, // convertable values
2073 TRACE_EVENT_FLAG_NONE); // flags 2083 TRACE_EVENT_FLAG_NONE); // flags
2074 } 2084 }
2075 } 2085 }
2076 2086
2077 } // namespace trace_event_internal 2087 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « no previous file | tools/valgrind/tsan_v2/suppressions.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698