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

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

Issue 89753004: Revert 237280 "Remove TraceController" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years 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 | « trunk/src/base/debug/trace_event_impl.h ('k') | trunk/src/base/debug/trace_event_unittest.cc » ('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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 const int g_category_trace_event_overhead = 3; 92 const int g_category_trace_event_overhead = 3;
93 const int g_num_builtin_categories = 4; 93 const int g_num_builtin_categories = 4;
94 int g_category_index = g_num_builtin_categories; // Skip default categories. 94 int g_category_index = g_num_builtin_categories; // Skip default categories.
95 95
96 // The name of the current thread. This is used to decide if the current 96 // The name of the current thread. This is used to decide if the current
97 // thread name has changed. We combine all the seen thread names into the 97 // thread name has changed. We combine all the seen thread names into the
98 // output name for the thread. 98 // output name for the thread.
99 LazyInstance<ThreadLocalPointer<const char> >::Leaky 99 LazyInstance<ThreadLocalPointer<const char> >::Leaky
100 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 100 g_current_thread_name = LAZY_INSTANCE_INITIALIZER;
101 101
102 const char kRecordUntilFull[] = "record-until-full";
103 const char kRecordContinuously[] = "record-continuously";
104 const char kEnableSampling[] = "enable-sampling";
105 const char kMonitorSampling[] = "monitor-sampling";
106
102 TimeTicks ThreadNow() { 107 TimeTicks ThreadNow() {
103 return TimeTicks::IsThreadNowSupported() ? 108 return TimeTicks::IsThreadNowSupported() ?
104 TimeTicks::ThreadNow() : TimeTicks(); 109 TimeTicks::ThreadNow() : TimeTicks();
105 } 110 }
106 111
107 class TraceBufferRingBuffer : public TraceBuffer { 112 class TraceBufferRingBuffer : public TraceBuffer {
108 public: 113 public:
109 TraceBufferRingBuffer(size_t max_chunks) 114 TraceBufferRingBuffer(size_t max_chunks)
110 : max_chunks_(max_chunks), 115 : max_chunks_(max_chunks),
111 recyclable_chunks_queue_(new size_t[queue_capacity()]), 116 recyclable_chunks_queue_(new size_t[queue_capacity()]),
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 // TraceLog 937 // TraceLog
933 // 938 //
934 //////////////////////////////////////////////////////////////////////////////// 939 ////////////////////////////////////////////////////////////////////////////////
935 940
936 class TraceLog::ThreadLocalEventBuffer 941 class TraceLog::ThreadLocalEventBuffer
937 : public MessageLoop::DestructionObserver { 942 : public MessageLoop::DestructionObserver {
938 public: 943 public:
939 ThreadLocalEventBuffer(TraceLog* trace_log); 944 ThreadLocalEventBuffer(TraceLog* trace_log);
940 virtual ~ThreadLocalEventBuffer(); 945 virtual ~ThreadLocalEventBuffer();
941 946
942 TraceEvent* AddTraceEvent(TraceEventHandle* handle); 947 TraceEvent* AddTraceEvent(NotificationHelper* notifier,
948 TraceEventHandle* handle);
943 949
944 void ReportOverhead(const TimeTicks& event_timestamp, 950 void ReportOverhead(const TimeTicks& event_timestamp,
945 const TimeTicks& event_thread_timestamp); 951 const TimeTicks& event_thread_timestamp,
952 NotificationHelper* notifier);
946 953
947 TraceEvent* GetEventByHandle(TraceEventHandle handle) { 954 TraceEvent* GetEventByHandle(TraceEventHandle handle) {
948 if (!chunk_ || handle.chunk_seq != chunk_->seq() || 955 if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
949 handle.chunk_index != chunk_index_) 956 handle.chunk_index != chunk_index_)
950 return NULL; 957 return NULL;
951 958
952 return chunk_->GetEventAt(handle.event_index); 959 return chunk_->GetEventAt(handle.event_index);
953 } 960 }
954 961
955 int generation() const { return generation_; } 962 int generation() const { return generation_; }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 999
993 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { 1000 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
994 CheckThisIsCurrentBuffer(); 1001 CheckThisIsCurrentBuffer();
995 MessageLoop::current()->RemoveDestructionObserver(this); 1002 MessageLoop::current()->RemoveDestructionObserver(this);
996 1003
997 // Zero event_count_ happens in either of the following cases: 1004 // Zero event_count_ happens in either of the following cases:
998 // - no event generated for the thread; 1005 // - no event generated for the thread;
999 // - the thread has no message loop; 1006 // - the thread has no message loop;
1000 // - trace_event_overhead is disabled. 1007 // - trace_event_overhead is disabled.
1001 if (event_count_) { 1008 if (event_count_) {
1002 InitializeMetadataEvent(AddTraceEvent(NULL), 1009 NotificationHelper notifier(trace_log_);
1010 InitializeMetadataEvent(AddTraceEvent(&notifier, NULL),
1003 static_cast<int>(base::PlatformThread::CurrentId()), 1011 static_cast<int>(base::PlatformThread::CurrentId()),
1004 "overhead", "average_overhead", 1012 "overhead", "average_overhead",
1005 overhead_.InMillisecondsF() / event_count_); 1013 overhead_.InMillisecondsF() / event_count_);
1014 notifier.SendNotificationIfAny();
1006 } 1015 }
1007 1016
1008 { 1017 {
1009 AutoLock lock(trace_log_->lock_); 1018 AutoLock lock(trace_log_->lock_);
1010 FlushWhileLocked(); 1019 FlushWhileLocked();
1011 trace_log_->thread_message_loops_.erase(MessageLoop::current()); 1020 trace_log_->thread_message_loops_.erase(MessageLoop::current());
1012 } 1021 }
1013 trace_log_->thread_local_event_buffer_.Set(NULL); 1022 trace_log_->thread_local_event_buffer_.Set(NULL);
1014 } 1023 }
1015 1024
1016 TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( 1025 TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
1026 NotificationHelper* notifier,
1017 TraceEventHandle* handle) { 1027 TraceEventHandle* handle) {
1018 CheckThisIsCurrentBuffer(); 1028 CheckThisIsCurrentBuffer();
1019 1029
1020 if (chunk_ && chunk_->IsFull()) { 1030 if (chunk_ && chunk_->IsFull()) {
1021 AutoLock lock(trace_log_->lock_); 1031 AutoLock lock(trace_log_->lock_);
1022 FlushWhileLocked(); 1032 FlushWhileLocked();
1023 chunk_.reset(); 1033 chunk_.reset();
1024 } 1034 }
1025 if (!chunk_) { 1035 if (!chunk_) {
1026 AutoLock lock(trace_log_->lock_); 1036 AutoLock lock(trace_log_->lock_);
1027 chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_); 1037 chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
1028 trace_log_->CheckIfBufferIsFullWhileLocked(); 1038 trace_log_->CheckIfBufferIsFullWhileLocked(notifier);
1029 } 1039 }
1030 if (!chunk_) 1040 if (!chunk_)
1031 return NULL; 1041 return NULL;
1032 1042
1033 size_t event_index; 1043 size_t event_index;
1034 TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index); 1044 TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index);
1035 if (trace_event && handle) 1045 if (trace_event && handle)
1036 MakeHandle(chunk_->seq(), chunk_index_, event_index, handle); 1046 MakeHandle(chunk_->seq(), chunk_index_, event_index, handle);
1037 1047
1038 return trace_event; 1048 return trace_event;
1039 } 1049 }
1040 1050
1041 void TraceLog::ThreadLocalEventBuffer::ReportOverhead( 1051 void TraceLog::ThreadLocalEventBuffer::ReportOverhead(
1042 const TimeTicks& event_timestamp, 1052 const TimeTicks& event_timestamp,
1043 const TimeTicks& event_thread_timestamp) { 1053 const TimeTicks& event_thread_timestamp,
1054 NotificationHelper* notifier) {
1044 if (!g_category_group_enabled[g_category_trace_event_overhead]) 1055 if (!g_category_group_enabled[g_category_trace_event_overhead])
1045 return; 1056 return;
1046 1057
1047 CheckThisIsCurrentBuffer(); 1058 CheckThisIsCurrentBuffer();
1048 1059
1049 event_count_++; 1060 event_count_++;
1050 TimeTicks now = trace_log_->OffsetNow(); 1061 TimeTicks now = trace_log_->OffsetNow();
1051 TimeDelta overhead = now - event_timestamp; 1062 TimeDelta overhead = now - event_timestamp;
1052 if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) { 1063 if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) {
1053 TraceEvent* trace_event = AddTraceEvent(NULL); 1064 TraceEvent* trace_event = AddTraceEvent(notifier, NULL);
1054 if (trace_event) { 1065 if (trace_event) {
1055 trace_event->Initialize( 1066 trace_event->Initialize(
1056 static_cast<int>(PlatformThread::CurrentId()), 1067 static_cast<int>(PlatformThread::CurrentId()),
1057 event_timestamp, event_thread_timestamp, 1068 event_timestamp, event_thread_timestamp,
1058 TRACE_EVENT_PHASE_COMPLETE, 1069 TRACE_EVENT_PHASE_COMPLETE,
1059 &g_category_group_enabled[g_category_trace_event_overhead], 1070 &g_category_group_enabled[g_category_trace_event_overhead],
1060 "overhead", 0, 0, NULL, NULL, NULL, NULL, 0); 1071 "overhead", 0, 0, NULL, NULL, NULL, NULL, 0);
1061 trace_event->UpdateDuration(now); 1072 trace_event->UpdateDuration(now);
1062 } 1073 }
1063 } 1074 }
(...skipping 10 matching lines...) Expand all
1074 1085
1075 trace_log_->lock_.AssertAcquired(); 1086 trace_log_->lock_.AssertAcquired();
1076 if (trace_log_->CheckGeneration(generation_)) { 1087 if (trace_log_->CheckGeneration(generation_)) {
1077 // Return the chunk to the buffer only if the generation matches, 1088 // Return the chunk to the buffer only if the generation matches,
1078 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); 1089 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass());
1079 } 1090 }
1080 // Otherwise this method may be called from the destructor, or TraceLog will 1091 // Otherwise this method may be called from the destructor, or TraceLog will
1081 // find the generation mismatch and delete this buffer soon. 1092 // find the generation mismatch and delete this buffer soon.
1082 } 1093 }
1083 1094
1095 TraceLog::NotificationHelper::NotificationHelper(TraceLog* trace_log)
1096 : trace_log_(trace_log),
1097 notification_(0) {
1098 }
1099
1100 TraceLog::NotificationHelper::~NotificationHelper() {
1101 }
1102
1103 void TraceLog::NotificationHelper::AddNotificationWhileLocked(
1104 int notification) {
1105 trace_log_->lock_.AssertAcquired();
1106 if (trace_log_->notification_callback_.is_null())
1107 return;
1108 if (notification_ == 0)
1109 callback_copy_ = trace_log_->notification_callback_;
1110 notification_ |= notification;
1111 }
1112
1113 void TraceLog::NotificationHelper::SendNotificationIfAny() {
1114 if (notification_)
1115 callback_copy_.Run(notification_);
1116 }
1117
1084 // static 1118 // static
1085 TraceLog* TraceLog::GetInstance() { 1119 TraceLog* TraceLog::GetInstance() {
1086 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); 1120 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get();
1087 } 1121 }
1088 1122
1123 // static
1124 // Note, if you add more options here you also need to update:
1125 // content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString
1126 TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) {
1127 std::vector<std::string> split;
1128 base::SplitString(options, ',', &split);
1129 int ret = 0;
1130 for (std::vector<std::string>::iterator iter = split.begin();
1131 iter != split.end();
1132 ++iter) {
1133 if (*iter == kRecordUntilFull) {
1134 ret |= RECORD_UNTIL_FULL;
1135 } else if (*iter == kRecordContinuously) {
1136 ret |= RECORD_CONTINUOUSLY;
1137 } else if (*iter == kEnableSampling) {
1138 ret |= ENABLE_SAMPLING;
1139 } else if (*iter == kMonitorSampling) {
1140 ret |= MONITOR_SAMPLING;
1141 } else {
1142 NOTREACHED(); // Unknown option provided.
1143 }
1144 }
1145 if (!(ret & RECORD_UNTIL_FULL) && !(ret & RECORD_CONTINUOUSLY))
1146 ret |= RECORD_UNTIL_FULL; // Default when no options are specified.
1147
1148 return static_cast<Options>(ret);
1149 }
1150
1089 TraceLog::TraceLog() 1151 TraceLog::TraceLog()
1090 : enabled_(false), 1152 : enabled_(false),
1091 num_traces_recorded_(0), 1153 num_traces_recorded_(0),
1154 buffer_is_full_(0),
1092 event_callback_(0), 1155 event_callback_(0),
1093 dispatching_to_observer_list_(false), 1156 dispatching_to_observer_list_(false),
1094 process_sort_index_(0), 1157 process_sort_index_(0),
1095 process_id_hash_(0), 1158 process_id_hash_(0),
1096 process_id_(0), 1159 process_id_(0),
1097 watch_category_(0), 1160 watch_category_(0),
1098 trace_options_(RECORD_UNTIL_FULL), 1161 trace_options_(RECORD_UNTIL_FULL),
1099 sampling_thread_handle_(0), 1162 sampling_thread_handle_(0),
1100 category_filter_(CategoryFilter::kDefaultCategoryFilterString), 1163 category_filter_(CategoryFilter::kDefaultCategoryFilterString),
1101 event_callback_category_filter_( 1164 event_callback_category_filter_(
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 "Cannot manipulate TraceLog::Enabled state from an observer."; 1321 "Cannot manipulate TraceLog::Enabled state from an observer.";
1259 return; 1322 return;
1260 } 1323 }
1261 1324
1262 enabled_ = true; 1325 enabled_ = true;
1263 1326
1264 if (options != old_options) { 1327 if (options != old_options) {
1265 subtle::NoBarrier_Store(&trace_options_, options); 1328 subtle::NoBarrier_Store(&trace_options_, options);
1266 logged_events_.reset(CreateTraceBuffer()); 1329 logged_events_.reset(CreateTraceBuffer());
1267 NextGeneration(); 1330 NextGeneration();
1331 subtle::NoBarrier_Store(&buffer_is_full_, 0);
1268 } 1332 }
1269 1333
1270 num_traces_recorded_++; 1334 num_traces_recorded_++;
1271 1335
1272 category_filter_ = CategoryFilter(category_filter); 1336 category_filter_ = CategoryFilter(category_filter);
1273 UpdateCategoryGroupEnabledFlags(); 1337 UpdateCategoryGroupEnabledFlags();
1274 1338
1275 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { 1339 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) {
1276 sampling_thread_.reset(new TraceSamplingThread); 1340 sampling_thread_.reset(new TraceSamplingThread);
1277 sampling_thread_->RegisterSampleBucket( 1341 sampling_thread_->RegisterSampleBucket(
(...skipping 26 matching lines...) Expand all
1304 dispatching_to_observer_list_ = false; 1368 dispatching_to_observer_list_ = false;
1305 } 1369 }
1306 } 1370 }
1307 1371
1308 CategoryFilter TraceLog::GetCurrentCategoryFilter() { 1372 CategoryFilter TraceLog::GetCurrentCategoryFilter() {
1309 AutoLock lock(lock_); 1373 AutoLock lock(lock_);
1310 return category_filter_; 1374 return category_filter_;
1311 } 1375 }
1312 1376
1313 void TraceLog::SetDisabled() { 1377 void TraceLog::SetDisabled() {
1314 AutoLock lock(lock_); 1378 std::vector<EnabledStateObserver*> observer_list;
1315 SetDisabledWhileLocked(); 1379 {
1316 } 1380 AutoLock lock(lock_);
1381 if (!enabled_)
1382 return;
1317 1383
1318 void TraceLog::SetDisabledWhileLocked() { 1384 if (dispatching_to_observer_list_) {
1319 lock_.AssertAcquired(); 1385 DLOG(ERROR)
1386 << "Cannot manipulate TraceLog::Enabled state from an observer.";
1387 return;
1388 }
1320 1389
1321 if (!enabled_) 1390 enabled_ = false;
1322 return;
1323 1391
1324 if (dispatching_to_observer_list_) { 1392 if (sampling_thread_.get()) {
1325 DLOG(ERROR) 1393 // Stop the sampling thread.
1326 << "Cannot manipulate TraceLog::Enabled state from an observer."; 1394 sampling_thread_->Stop();
1327 return; 1395 lock_.Release();
1396 PlatformThread::Join(sampling_thread_handle_);
1397 lock_.Acquire();
1398 sampling_thread_handle_ = PlatformThreadHandle();
1399 sampling_thread_.reset();
1400 }
1401
1402 category_filter_.Clear();
1403 subtle::NoBarrier_Store(&watch_category_, 0);
1404 watch_event_name_ = "";
1405 UpdateCategoryGroupEnabledFlags();
1406 AddMetadataEventsWhileLocked();
1407
1408 dispatching_to_observer_list_ = true;
1409 observer_list = enabled_state_observer_list_;
1328 } 1410 }
1329 1411
1330 enabled_ = false; 1412 // Dispatch to observers outside the lock in case the observer triggers a
1331 1413 // trace event.
1332 if (sampling_thread_.get()) { 1414 for (size_t i = 0; i < observer_list.size(); ++i)
1333 // Stop the sampling thread. 1415 observer_list[i]->OnTraceLogDisabled();
1334 sampling_thread_->Stop();
1335 lock_.Release();
1336 PlatformThread::Join(sampling_thread_handle_);
1337 lock_.Acquire();
1338 sampling_thread_handle_ = PlatformThreadHandle();
1339 sampling_thread_.reset();
1340 }
1341
1342 category_filter_.Clear();
1343 subtle::NoBarrier_Store(&watch_category_, 0);
1344 watch_event_name_ = "";
1345 UpdateCategoryGroupEnabledFlags();
1346 AddMetadataEventsWhileLocked();
1347
1348 dispatching_to_observer_list_ = true;
1349 std::vector<EnabledStateObserver*> observer_list =
1350 enabled_state_observer_list_;
1351 1416
1352 { 1417 {
1353 // Dispatch to observers outside the lock in case the observer triggers a 1418 AutoLock lock(lock_);
1354 // trace event. 1419 dispatching_to_observer_list_ = false;
1355 AutoUnlock unlock(lock_);
1356 for (size_t i = 0; i < observer_list.size(); ++i)
1357 observer_list[i]->OnTraceLogDisabled();
1358 } 1420 }
1359 dispatching_to_observer_list_ = false;
1360 } 1421 }
1361 1422
1362 int TraceLog::GetNumTracesRecorded() { 1423 int TraceLog::GetNumTracesRecorded() {
1363 AutoLock lock(lock_); 1424 AutoLock lock(lock_);
1364 if (!enabled_) 1425 if (!enabled_)
1365 return -1; 1426 return -1;
1366 return num_traces_recorded_; 1427 return num_traces_recorded_;
1367 } 1428 }
1368 1429
1369 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { 1430 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) {
(...skipping 11 matching lines...) Expand all
1381 1442
1382 bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const { 1443 bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const {
1383 std::vector<EnabledStateObserver*>::const_iterator it = 1444 std::vector<EnabledStateObserver*>::const_iterator it =
1384 std::find(enabled_state_observer_list_.begin(), 1445 std::find(enabled_state_observer_list_.begin(),
1385 enabled_state_observer_list_.end(), 1446 enabled_state_observer_list_.end(),
1386 listener); 1447 listener);
1387 return it != enabled_state_observer_list_.end(); 1448 return it != enabled_state_observer_list_.end();
1388 } 1449 }
1389 1450
1390 float TraceLog::GetBufferPercentFull() const { 1451 float TraceLog::GetBufferPercentFull() const {
1391 AutoLock lock(lock_);
1392 return static_cast<float>(static_cast<double>(logged_events_->Size()) / 1452 return static_cast<float>(static_cast<double>(logged_events_->Size()) /
1393 logged_events_->Capacity()); 1453 logged_events_->Capacity());
1394 } 1454 }
1395 1455
1396 bool TraceLog::BufferIsFull() const { 1456 void TraceLog::SetNotificationCallback(
1457 const TraceLog::NotificationCallback& cb) {
1397 AutoLock lock(lock_); 1458 AutoLock lock(lock_);
1398 return logged_events_->IsFull(); 1459 notification_callback_ = cb;
1399 } 1460 }
1400 1461
1401 TraceBuffer* TraceLog::CreateTraceBuffer() { 1462 TraceBuffer* TraceLog::CreateTraceBuffer() {
1402 Options options = trace_options(); 1463 Options options = trace_options();
1403 if (options & RECORD_CONTINUOUSLY) 1464 if (options & RECORD_CONTINUOUSLY)
1404 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); 1465 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks);
1405 else if (options & MONITOR_SAMPLING) 1466 else if (options & MONITOR_SAMPLING)
1406 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); 1467 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks);
1407 else if (options & ECHO_TO_CONSOLE) 1468 else if (options & ECHO_TO_CONSOLE)
1408 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); 1469 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks);
1409 return new TraceBufferVector(); 1470 return new TraceBufferVector();
1410 } 1471 }
1411 1472
1412 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( 1473 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
1413 TraceEventHandle* handle, bool check_buffer_is_full) { 1474 NotificationHelper* notifier, TraceEventHandle* handle) {
1414 lock_.AssertAcquired(); 1475 lock_.AssertAcquired();
1415 1476
1416 if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) { 1477 if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
1417 logged_events_->ReturnChunk(thread_shared_chunk_index_, 1478 logged_events_->ReturnChunk(thread_shared_chunk_index_,
1418 thread_shared_chunk_.Pass()); 1479 thread_shared_chunk_.Pass());
1419 } 1480 }
1420 1481
1421 if (!thread_shared_chunk_) { 1482 if (!thread_shared_chunk_) {
1422 thread_shared_chunk_ = logged_events_->GetChunk( 1483 thread_shared_chunk_ = logged_events_->GetChunk(
1423 &thread_shared_chunk_index_); 1484 &thread_shared_chunk_index_);
1424 if (check_buffer_is_full) 1485 if (notifier)
1425 CheckIfBufferIsFullWhileLocked(); 1486 CheckIfBufferIsFullWhileLocked(notifier);
1426 } 1487 }
1427 if (!thread_shared_chunk_) 1488 if (!thread_shared_chunk_)
1428 return NULL; 1489 return NULL;
1429 1490
1430 size_t event_index; 1491 size_t event_index;
1431 TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index); 1492 TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index);
1432 if (trace_event && handle) { 1493 if (trace_event && handle) {
1433 MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_, 1494 MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_,
1434 event_index, handle); 1495 event_index, handle);
1435 } 1496 }
1436 return trace_event; 1497 return trace_event;
1437 } 1498 }
1438 1499
1439 void TraceLog::CheckIfBufferIsFullWhileLocked() { 1500 void TraceLog::CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier) {
1440 lock_.AssertAcquired(); 1501 lock_.AssertAcquired();
1441 if (logged_events_->IsFull()) 1502 if (!subtle::NoBarrier_Load(&buffer_is_full_) && logged_events_->IsFull()) {
1442 SetDisabledWhileLocked(); 1503 subtle::NoBarrier_Store(&buffer_is_full_,
1504 static_cast<subtle::AtomicWord>(1));
1505 notifier->AddNotificationWhileLocked(TRACE_BUFFER_FULL);
1506 }
1443 } 1507 }
1444 1508
1445 void TraceLog::SetEventCallbackEnabled(const CategoryFilter& category_filter, 1509 void TraceLog::SetEventCallbackEnabled(const CategoryFilter& category_filter,
1446 EventCallback cb) { 1510 EventCallback cb) {
1447 AutoLock lock(lock_); 1511 AutoLock lock(lock_);
1448 subtle::NoBarrier_Store(&event_callback_, 1512 subtle::NoBarrier_Store(&event_callback_,
1449 reinterpret_cast<subtle::AtomicWord>(cb)); 1513 reinterpret_cast<subtle::AtomicWord>(cb));
1450 event_callback_category_filter_ = category_filter; 1514 event_callback_category_filter_ = category_filter;
1451 UpdateCategoryGroupEnabledFlags(); 1515 UpdateCategoryGroupEnabledFlags();
1452 }; 1516 };
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 1613
1550 if (!CheckGeneration(generation)) 1614 if (!CheckGeneration(generation))
1551 return; 1615 return;
1552 1616
1553 { 1617 {
1554 AutoLock lock(lock_); 1618 AutoLock lock(lock_);
1555 1619
1556 previous_logged_events.swap(logged_events_); 1620 previous_logged_events.swap(logged_events_);
1557 logged_events_.reset(CreateTraceBuffer()); 1621 logged_events_.reset(CreateTraceBuffer());
1558 NextGeneration(); 1622 NextGeneration();
1623 subtle::NoBarrier_Store(&buffer_is_full_, 0);
1559 thread_message_loops_.clear(); 1624 thread_message_loops_.clear();
1560 1625
1561 flush_message_loop_proxy_ = NULL; 1626 flush_message_loop_proxy_ = NULL;
1562 flush_output_callback = flush_output_callback_; 1627 flush_output_callback = flush_output_callback_;
1563 flush_output_callback_.Reset(); 1628 flush_output_callback_.Reset();
1564 } 1629 }
1565 1630
1566 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 1631 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(),
1567 flush_output_callback); 1632 flush_output_callback);
1568 } 1633 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1668 return handle; 1733 return handle;
1669 1734
1670 DCHECK(name); 1735 DCHECK(name);
1671 1736
1672 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 1737 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
1673 id ^= process_id_hash_; 1738 id ^= process_id_hash_;
1674 1739
1675 TimeTicks now = OffsetTimestamp(timestamp); 1740 TimeTicks now = OffsetTimestamp(timestamp);
1676 TimeTicks thread_now = ThreadNow(); 1741 TimeTicks thread_now = ThreadNow();
1677 1742
1743 NotificationHelper notifier(this);
1744
1678 ThreadLocalEventBuffer* thread_local_event_buffer = NULL; 1745 ThreadLocalEventBuffer* thread_local_event_buffer = NULL;
1679 // A ThreadLocalEventBuffer needs the message loop 1746 // A ThreadLocalEventBuffer needs the message loop
1680 // - to know when the thread exits; 1747 // - to know when the thread exits;
1681 // - to handle the final flush. 1748 // - to handle the final flush.
1682 // For a thread without a message loop or the message loop may be blocked, the 1749 // For a thread without a message loop or the message loop may be blocked, the
1683 // trace events will be added into the main buffer directly. 1750 // trace events will be added into the main buffer directly.
1684 if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) { 1751 if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) {
1685 thread_local_event_buffer = thread_local_event_buffer_.Get(); 1752 thread_local_event_buffer = thread_local_event_buffer_.Get();
1686 if (thread_local_event_buffer && 1753 if (thread_local_event_buffer &&
1687 !CheckGeneration(thread_local_event_buffer->generation())) { 1754 !CheckGeneration(thread_local_event_buffer->generation())) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 new_name) != existing_names.end(); 1791 new_name) != existing_names.end();
1725 if (!found) { 1792 if (!found) {
1726 existing_name->second.push_back(','); 1793 existing_name->second.push_back(',');
1727 existing_name->second.append(new_name); 1794 existing_name->second.append(new_name);
1728 } 1795 }
1729 } 1796 }
1730 } 1797 }
1731 } 1798 }
1732 1799
1733 TraceEvent* trace_event = NULL; 1800 TraceEvent* trace_event = NULL;
1734 if ((*category_group_enabled & ENABLED_FOR_RECORDING)) { 1801 if ((*category_group_enabled & ENABLED_FOR_RECORDING) &&
1802 !subtle::NoBarrier_Load(&buffer_is_full_)) {
1735 if (thread_local_event_buffer) { 1803 if (thread_local_event_buffer) {
1736 lock.EnsureReleased(); 1804 lock.EnsureReleased();
1737 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); 1805 trace_event = thread_local_event_buffer->AddTraceEvent(&notifier,
1806 &handle);
1738 } else { 1807 } else {
1739 lock.EnsureAcquired(); 1808 lock.EnsureAcquired();
1740 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); 1809 trace_event = AddEventToThreadSharedChunkWhileLocked(&notifier, &handle);
1741 } 1810 }
1742 1811
1743 if (trace_event) { 1812 if (trace_event) {
1744 trace_event->Initialize(thread_id, now, thread_now, phase, 1813 trace_event->Initialize(thread_id, now, thread_now, phase,
1745 category_group_enabled, name, id, 1814 category_group_enabled, name, id,
1746 num_args, arg_names, arg_types, arg_values, 1815 num_args, arg_names, arg_types, arg_values,
1747 convertable_values, flags); 1816 convertable_values, flags);
1748 1817
1749 #if defined(OS_ANDROID) 1818 #if defined(OS_ANDROID)
1750 trace_event->SendToATrace(); 1819 trace_event->SendToATrace();
1751 #endif 1820 #endif
1752 } 1821 }
1822 }
1753 1823
1754 if (trace_options() & ECHO_TO_CONSOLE) { 1824 if (trace_options() & ECHO_TO_CONSOLE) {
1755 lock.EnsureAcquired(); 1825 lock.EnsureAcquired();
1756 OutputEventToConsoleWhileLocked( 1826 OutputEventToConsoleWhileLocked(
1757 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, 1827 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
1758 timestamp, trace_event); 1828 timestamp, trace_event);
1759 }
1760 } 1829 }
1761 1830
1762 if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load( 1831 if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load(
1763 &watch_category_)) == category_group_enabled) { 1832 &watch_category_)) == category_group_enabled) {
1764 lock.EnsureAcquired(); 1833 lock.EnsureAcquired();
1765 if (watch_event_name_ == name) { 1834 if (watch_event_name_ == name)
1766 WatchEventCallback watch_event_callback_copy = watch_event_callback_; 1835 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
1767 lock.EnsureReleased();
1768 if (!watch_event_callback_copy.is_null())
1769 watch_event_callback_copy.Run();
1770 }
1771 } 1836 }
1772 1837
1773 lock.EnsureReleased(); 1838 lock.EnsureReleased();
1774 if (*category_group_enabled & ENABLED_FOR_EVENT_CALLBACK) { 1839 if (*category_group_enabled & ENABLED_FOR_EVENT_CALLBACK) {
1775 EventCallback event_callback = reinterpret_cast<EventCallback>( 1840 EventCallback event_callback = reinterpret_cast<EventCallback>(
1776 subtle::NoBarrier_Load(&event_callback_)); 1841 subtle::NoBarrier_Load(&event_callback_));
1777 if (event_callback) { 1842 if (event_callback) {
1778 event_callback(now, 1843 event_callback(now,
1779 phase == TRACE_EVENT_PHASE_COMPLETE ? 1844 phase == TRACE_EVENT_PHASE_COMPLETE ?
1780 TRACE_EVENT_PHASE_BEGIN : phase, 1845 TRACE_EVENT_PHASE_BEGIN : phase,
1781 category_group_enabled, name, id, 1846 category_group_enabled, name, id,
1782 num_args, arg_names, arg_types, arg_values, 1847 num_args, arg_names, arg_types, arg_values,
1783 flags); 1848 flags);
1784 } 1849 }
1785 } 1850 }
1786 1851
1787 if (thread_local_event_buffer) 1852 if (thread_local_event_buffer)
1788 thread_local_event_buffer->ReportOverhead(now, thread_now); 1853 thread_local_event_buffer->ReportOverhead(now, thread_now, &notifier);
1854
1855 notifier.SendNotificationIfAny();
1789 1856
1790 return handle; 1857 return handle;
1791 } 1858 }
1792 1859
1793 // May be called when a COMPELETE event ends and the unfinished event has been 1860 // May be called when a COMPELETE event ends and the unfinished event has been
1794 // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL). 1861 // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL).
1795 void TraceLog::OutputEventToConsoleWhileLocked(unsigned char phase, 1862 void TraceLog::OutputEventToConsoleWhileLocked(unsigned char phase,
1796 const TimeTicks& timestamp, 1863 const TimeTicks& timestamp,
1797 TraceEvent* trace_event) { 1864 TraceEvent* trace_event) {
1798 // The caller should translate TRACE_EVENT_PHASE_COMPLETE to 1865 // The caller should translate TRACE_EVENT_PHASE_COMPLETE to
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 subtle::NoBarrier_Load(&event_callback_)); 1955 subtle::NoBarrier_Load(&event_callback_));
1889 if (event_callback) { 1956 if (event_callback) {
1890 event_callback(now, TRACE_EVENT_PHASE_END, category_group_enabled, name, 1957 event_callback(now, TRACE_EVENT_PHASE_END, category_group_enabled, name,
1891 trace_event_internal::kNoEventId, 0, NULL, NULL, NULL, 1958 trace_event_internal::kNoEventId, 0, NULL, NULL, NULL,
1892 TRACE_EVENT_FLAG_NONE); 1959 TRACE_EVENT_FLAG_NONE);
1893 } 1960 }
1894 } 1961 }
1895 } 1962 }
1896 1963
1897 void TraceLog::SetWatchEvent(const std::string& category_name, 1964 void TraceLog::SetWatchEvent(const std::string& category_name,
1898 const std::string& event_name, 1965 const std::string& event_name) {
1899 const WatchEventCallback& callback) {
1900 const unsigned char* category = GetCategoryGroupEnabled( 1966 const unsigned char* category = GetCategoryGroupEnabled(
1901 category_name.c_str()); 1967 category_name.c_str());
1902 AutoLock lock(lock_); 1968 AutoLock lock(lock_);
1903 subtle::NoBarrier_Store(&watch_category_, 1969 subtle::NoBarrier_Store(&watch_category_,
1904 reinterpret_cast<subtle::AtomicWord>(category)); 1970 reinterpret_cast<subtle::AtomicWord>(category));
1905 watch_event_name_ = event_name; 1971 watch_event_name_ = event_name;
1906 watch_event_callback_ = callback;
1907 } 1972 }
1908 1973
1909 void TraceLog::CancelWatchEvent() { 1974 void TraceLog::CancelWatchEvent() {
1910 AutoLock lock(lock_); 1975 AutoLock lock(lock_);
1911 subtle::NoBarrier_Store(&watch_category_, 0); 1976 subtle::NoBarrier_Store(&watch_category_, 0);
1912 watch_event_name_ = ""; 1977 watch_event_name_ = "";
1913 watch_event_callback_.Reset();
1914 } 1978 }
1915 1979
1916 void TraceLog::AddMetadataEventsWhileLocked() { 1980 void TraceLog::AddMetadataEventsWhileLocked() {
1917 lock_.AssertAcquired(); 1981 lock_.AssertAcquired();
1918 1982
1919 int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 1983 int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1920 if (process_sort_index_ != 0) { 1984 if (process_sort_index_ != 0) {
1921 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 1985 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
1922 current_thread_id, 1986 current_thread_id,
1923 "process_sort_index", "sort_index", 1987 "process_sort_index", "sort_index",
1924 process_sort_index_); 1988 process_sort_index_);
1925 } 1989 }
1926 1990
1927 if (process_name_.size()) { 1991 if (process_name_.size()) {
1928 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 1992 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
1929 current_thread_id, 1993 current_thread_id,
1930 "process_name", "name", 1994 "process_name", "name",
1931 process_name_); 1995 process_name_);
1932 } 1996 }
1933 1997
1934 if (process_labels_.size() > 0) { 1998 if (process_labels_.size() > 0) {
1935 std::vector<std::string> labels; 1999 std::vector<std::string> labels;
1936 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin(); 2000 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin();
1937 it != process_labels_.end(); 2001 it != process_labels_.end();
1938 it++) { 2002 it++) {
1939 labels.push_back(it->second); 2003 labels.push_back(it->second);
1940 } 2004 }
1941 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2005 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
1942 current_thread_id, 2006 current_thread_id,
1943 "process_labels", "labels", 2007 "process_labels", "labels",
1944 JoinString(labels, ',')); 2008 JoinString(labels, ','));
1945 } 2009 }
1946 2010
1947 // Thread sort indices. 2011 // Thread sort indices.
1948 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin(); 2012 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin();
1949 it != thread_sort_indices_.end(); 2013 it != thread_sort_indices_.end();
1950 it++) { 2014 it++) {
1951 if (it->second == 0) 2015 if (it->second == 0)
1952 continue; 2016 continue;
1953 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2017 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
1954 it->first, 2018 it->first,
1955 "thread_sort_index", "sort_index", 2019 "thread_sort_index", "sort_index",
1956 it->second); 2020 it->second);
1957 } 2021 }
1958 2022
1959 // Thread names. 2023 // Thread names.
1960 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); 2024 for(hash_map<int, std::string>::iterator it = thread_names_.begin();
1961 it != thread_names_.end(); 2025 it != thread_names_.end();
1962 it++) { 2026 it++) {
1963 if (it->second.empty()) 2027 if (it->second.empty())
1964 continue; 2028 continue;
1965 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2029 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL),
1966 it->first, 2030 it->first,
1967 "thread_name", "name", 2031 "thread_name", "name",
1968 it->second); 2032 it->second);
1969 } 2033 }
1970 } 2034 }
1971 2035
1972 void TraceLog::WaitSamplingEventForTesting() { 2036 void TraceLog::WaitSamplingEventForTesting() {
1973 if (!sampling_thread_) 2037 if (!sampling_thread_)
1974 return; 2038 return;
1975 sampling_thread_->WaitSamplingEventForTesting(); 2039 sampling_thread_->WaitSamplingEventForTesting();
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 } 2314 }
2251 2315
2252 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2316 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2253 if (*category_group_enabled_) { 2317 if (*category_group_enabled_) {
2254 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2318 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_,
2255 name_, event_handle_); 2319 name_, event_handle_);
2256 } 2320 }
2257 } 2321 }
2258 2322
2259 } // namespace trace_event_internal 2323 } // namespace trace_event_internal
OLDNEW
« no previous file with comments | « trunk/src/base/debug/trace_event_impl.h ('k') | trunk/src/base/debug/trace_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698