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

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

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

Powered by Google App Engine
This is Rietveld 408576698