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

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

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