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

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

Issue 67683003: Remove TraceController (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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
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 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 // TraceLog 932 // TraceLog
938 // 933 //
939 //////////////////////////////////////////////////////////////////////////////// 934 ////////////////////////////////////////////////////////////////////////////////
940 935
941 class TraceLog::ThreadLocalEventBuffer 936 class TraceLog::ThreadLocalEventBuffer
942 : public MessageLoop::DestructionObserver { 937 : public MessageLoop::DestructionObserver {
943 public: 938 public:
944 ThreadLocalEventBuffer(TraceLog* trace_log); 939 ThreadLocalEventBuffer(TraceLog* trace_log);
945 virtual ~ThreadLocalEventBuffer(); 940 virtual ~ThreadLocalEventBuffer();
946 941
947 TraceEvent* AddTraceEvent(NotificationHelper* notifier, 942 TraceEvent* AddTraceEvent(TraceEventHandle* handle);
948 TraceEventHandle* handle);
949 943
950 void ReportOverhead(const TimeTicks& event_timestamp, 944 void ReportOverhead(const TimeTicks& event_timestamp,
951 const TimeTicks& event_thread_timestamp, 945 const TimeTicks& event_thread_timestamp);
952 NotificationHelper* notifier);
953 946
954 TraceEvent* GetEventByHandle(TraceEventHandle handle) { 947 TraceEvent* GetEventByHandle(TraceEventHandle handle) {
955 if (!chunk_ || handle.chunk_seq != chunk_->seq() || 948 if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
956 handle.chunk_index != chunk_index_) 949 handle.chunk_index != chunk_index_)
957 return NULL; 950 return NULL;
958 951
959 return chunk_->GetEventAt(handle.event_index); 952 return chunk_->GetEventAt(handle.event_index);
960 } 953 }
961 954
962 int generation() const { return generation_; } 955 int generation() const { return generation_; }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 992
1000 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { 993 TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
1001 CheckThisIsCurrentBuffer(); 994 CheckThisIsCurrentBuffer();
1002 MessageLoop::current()->RemoveDestructionObserver(this); 995 MessageLoop::current()->RemoveDestructionObserver(this);
1003 996
1004 // Zero event_count_ happens in either of the following cases: 997 // Zero event_count_ happens in either of the following cases:
1005 // - no event generated for the thread; 998 // - no event generated for the thread;
1006 // - the thread has no message loop; 999 // - the thread has no message loop;
1007 // - trace_event_overhead is disabled. 1000 // - trace_event_overhead is disabled.
1008 if (event_count_) { 1001 if (event_count_) {
1009 NotificationHelper notifier(trace_log_); 1002 InitializeMetadataEvent(AddTraceEvent(NULL),
1010 InitializeMetadataEvent(AddTraceEvent(&notifier, NULL),
1011 static_cast<int>(base::PlatformThread::CurrentId()), 1003 static_cast<int>(base::PlatformThread::CurrentId()),
1012 "overhead", "average_overhead", 1004 "overhead", "average_overhead",
1013 overhead_.InMillisecondsF() / event_count_); 1005 overhead_.InMillisecondsF() / event_count_);
1014 notifier.SendNotificationIfAny();
1015 } 1006 }
1016 1007
1017 { 1008 {
1018 AutoLock lock(trace_log_->lock_); 1009 AutoLock lock(trace_log_->lock_);
1019 FlushWhileLocked(); 1010 FlushWhileLocked();
1020 trace_log_->thread_message_loops_.erase(MessageLoop::current()); 1011 trace_log_->thread_message_loops_.erase(MessageLoop::current());
1021 } 1012 }
1022 trace_log_->thread_local_event_buffer_.Set(NULL); 1013 trace_log_->thread_local_event_buffer_.Set(NULL);
1023 } 1014 }
1024 1015
1025 TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( 1016 TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
1026 NotificationHelper* notifier,
1027 TraceEventHandle* handle) { 1017 TraceEventHandle* handle) {
1028 CheckThisIsCurrentBuffer(); 1018 CheckThisIsCurrentBuffer();
1029 1019
1030 if (chunk_ && chunk_->IsFull()) { 1020 if (chunk_ && chunk_->IsFull()) {
1031 AutoLock lock(trace_log_->lock_); 1021 AutoLock lock(trace_log_->lock_);
1032 FlushWhileLocked(); 1022 FlushWhileLocked();
1033 chunk_.reset(); 1023 chunk_.reset();
1034 } 1024 }
1035 if (!chunk_) { 1025 if (!chunk_) {
1036 AutoLock lock(trace_log_->lock_); 1026 AutoLock lock(trace_log_->lock_);
1037 chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_); 1027 chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
1038 trace_log_->CheckIfBufferIsFullWhileLocked(notifier); 1028 trace_log_->CheckIfBufferIsFullWhileLocked();
1039 } 1029 }
1040 if (!chunk_) 1030 if (!chunk_)
1041 return NULL; 1031 return NULL;
1042 1032
1043 size_t event_index; 1033 size_t event_index;
1044 TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index); 1034 TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index);
1045 if (trace_event && handle) 1035 if (trace_event && handle)
1046 MakeHandle(chunk_->seq(), chunk_index_, event_index, handle); 1036 MakeHandle(chunk_->seq(), chunk_index_, event_index, handle);
1047 1037
1048 return trace_event; 1038 return trace_event;
1049 } 1039 }
1050 1040
1051 void TraceLog::ThreadLocalEventBuffer::ReportOverhead( 1041 void TraceLog::ThreadLocalEventBuffer::ReportOverhead(
1052 const TimeTicks& event_timestamp, 1042 const TimeTicks& event_timestamp,
1053 const TimeTicks& event_thread_timestamp, 1043 const TimeTicks& event_thread_timestamp) {
1054 NotificationHelper* notifier) {
1055 if (!g_category_group_enabled[g_category_trace_event_overhead]) 1044 if (!g_category_group_enabled[g_category_trace_event_overhead])
1056 return; 1045 return;
1057 1046
1058 CheckThisIsCurrentBuffer(); 1047 CheckThisIsCurrentBuffer();
1059 1048
1060 event_count_++; 1049 event_count_++;
1061 TimeTicks now = trace_log_->OffsetNow(); 1050 TimeTicks now = trace_log_->OffsetNow();
1062 TimeDelta overhead = now - event_timestamp; 1051 TimeDelta overhead = now - event_timestamp;
1063 if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) { 1052 if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) {
1064 TraceEvent* trace_event = AddTraceEvent(notifier, NULL); 1053 TraceEvent* trace_event = AddTraceEvent(NULL);
1065 if (trace_event) { 1054 if (trace_event) {
1066 trace_event->Initialize( 1055 trace_event->Initialize(
1067 static_cast<int>(PlatformThread::CurrentId()), 1056 static_cast<int>(PlatformThread::CurrentId()),
1068 event_timestamp, event_thread_timestamp, 1057 event_timestamp, event_thread_timestamp,
1069 TRACE_EVENT_PHASE_COMPLETE, 1058 TRACE_EVENT_PHASE_COMPLETE,
1070 &g_category_group_enabled[g_category_trace_event_overhead], 1059 &g_category_group_enabled[g_category_trace_event_overhead],
1071 "overhead", 0, 0, NULL, NULL, NULL, NULL, 0); 1060 "overhead", 0, 0, NULL, NULL, NULL, NULL, 0);
1072 trace_event->UpdateDuration(now); 1061 trace_event->UpdateDuration(now);
1073 } 1062 }
1074 } 1063 }
(...skipping 10 matching lines...) Expand all
1085 1074
1086 trace_log_->lock_.AssertAcquired(); 1075 trace_log_->lock_.AssertAcquired();
1087 if (trace_log_->CheckGeneration(generation_)) { 1076 if (trace_log_->CheckGeneration(generation_)) {
1088 // Return the chunk to the buffer only if the generation matches, 1077 // Return the chunk to the buffer only if the generation matches,
1089 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); 1078 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass());
1090 } 1079 }
1091 // Otherwise this method may be called from the destructor, or TraceLog will 1080 // Otherwise this method may be called from the destructor, or TraceLog will
1092 // find the generation mismatch and delete this buffer soon. 1081 // find the generation mismatch and delete this buffer soon.
1093 } 1082 }
1094 1083
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
1118 // static 1084 // static
1119 TraceLog* TraceLog::GetInstance() { 1085 TraceLog* TraceLog::GetInstance() {
1120 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); 1086 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get();
1121 } 1087 }
1122 1088
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
1151 TraceLog::TraceLog() 1089 TraceLog::TraceLog()
1152 : enable_count_(0), 1090 : enable_count_(0),
1153 num_traces_recorded_(0), 1091 num_traces_recorded_(0),
1154 buffer_is_full_(0),
1155 event_callback_(0), 1092 event_callback_(0),
1156 dispatching_to_observer_list_(false), 1093 dispatching_to_observer_list_(false),
1157 process_sort_index_(0), 1094 process_sort_index_(0),
1158 process_id_hash_(0), 1095 process_id_hash_(0),
1159 process_id_(0), 1096 process_id_(0),
1160 watch_category_(0), 1097 watch_category_(0),
1161 trace_options_(RECORD_UNTIL_FULL), 1098 trace_options_(RECORD_UNTIL_FULL),
1162 sampling_thread_handle_(0), 1099 sampling_thread_handle_(0),
1163 category_filter_(CategoryFilter::kDefaultCategoryFilterString), 1100 category_filter_(CategoryFilter::kDefaultCategoryFilterString),
1164 thread_shared_chunk_index_(0), 1101 thread_shared_chunk_index_(0),
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 1244
1308 category_filter_.Merge(category_filter); 1245 category_filter_.Merge(category_filter);
1309 UpdateCategoryGroupEnabledFlags(); 1246 UpdateCategoryGroupEnabledFlags();
1310 return; 1247 return;
1311 } 1248 }
1312 1249
1313 if (options != old_options) { 1250 if (options != old_options) {
1314 subtle::NoBarrier_Store(&trace_options_, options); 1251 subtle::NoBarrier_Store(&trace_options_, options);
1315 logged_events_.reset(CreateTraceBuffer()); 1252 logged_events_.reset(CreateTraceBuffer());
1316 NextGeneration(); 1253 NextGeneration();
1317 subtle::NoBarrier_Store(&buffer_is_full_, 0);
1318 } 1254 }
1319 1255
1320 if (dispatching_to_observer_list_) { 1256 if (dispatching_to_observer_list_) {
1321 DLOG(ERROR) << 1257 DLOG(ERROR) <<
1322 "Cannot manipulate TraceLog::Enabled state from an observer."; 1258 "Cannot manipulate TraceLog::Enabled state from an observer.";
1323 return; 1259 return;
1324 } 1260 }
1325 1261
1326 num_traces_recorded_++; 1262 num_traces_recorded_++;
1327 1263
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 1371
1436 bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const { 1372 bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const {
1437 std::vector<EnabledStateObserver*>::const_iterator it = 1373 std::vector<EnabledStateObserver*>::const_iterator it =
1438 std::find(enabled_state_observer_list_.begin(), 1374 std::find(enabled_state_observer_list_.begin(),
1439 enabled_state_observer_list_.end(), 1375 enabled_state_observer_list_.end(),
1440 listener); 1376 listener);
1441 return it != enabled_state_observer_list_.end(); 1377 return it != enabled_state_observer_list_.end();
1442 } 1378 }
1443 1379
1444 float TraceLog::GetBufferPercentFull() const { 1380 float TraceLog::GetBufferPercentFull() const {
1381 AutoLock lock(lock_);
1445 return static_cast<float>(static_cast<double>(logged_events_->Size()) / 1382 return static_cast<float>(static_cast<double>(logged_events_->Size()) /
1446 logged_events_->Capacity()); 1383 logged_events_->Capacity());
1447 } 1384 }
1448 1385
1449 void TraceLog::SetNotificationCallback( 1386 bool TraceLog::BufferIsFull() const {
1450 const TraceLog::NotificationCallback& cb) {
1451 AutoLock lock(lock_); 1387 AutoLock lock(lock_);
1452 notification_callback_ = cb; 1388 return logged_events_->IsFull();
1453 } 1389 }
1454 1390
1455 TraceBuffer* TraceLog::CreateTraceBuffer() { 1391 TraceBuffer* TraceLog::CreateTraceBuffer() {
1456 Options options = trace_options(); 1392 Options options = trace_options();
1457 if (options & RECORD_CONTINUOUSLY) 1393 if (options & RECORD_CONTINUOUSLY)
1458 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); 1394 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks);
1459 else if (options & MONITOR_SAMPLING) 1395 else if (options & MONITOR_SAMPLING)
1460 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); 1396 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks);
1461 else if (options & ECHO_TO_CONSOLE) 1397 else if (options & ECHO_TO_CONSOLE)
1462 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); 1398 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks);
1463 return new TraceBufferVector(); 1399 return new TraceBufferVector();
1464 } 1400 }
1465 1401
1466 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( 1402 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
1467 NotificationHelper* notifier, TraceEventHandle* handle) { 1403 TraceEventHandle* handle) {
1468 lock_.AssertAcquired(); 1404 lock_.AssertAcquired();
1469 1405
1470 if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) { 1406 if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
1471 logged_events_->ReturnChunk(thread_shared_chunk_index_, 1407 logged_events_->ReturnChunk(thread_shared_chunk_index_,
1472 thread_shared_chunk_.Pass()); 1408 thread_shared_chunk_.Pass());
1473 } 1409 }
1474 1410
1475 if (!thread_shared_chunk_) { 1411 if (!thread_shared_chunk_) {
1476 thread_shared_chunk_ = logged_events_->GetChunk( 1412 thread_shared_chunk_ = logged_events_->GetChunk(
1477 &thread_shared_chunk_index_); 1413 &thread_shared_chunk_index_);
1478 if (notifier) 1414 CheckIfBufferIsFullWhileLocked();
1479 CheckIfBufferIsFullWhileLocked(notifier);
1480 } 1415 }
1481 if (!thread_shared_chunk_) 1416 if (!thread_shared_chunk_)
1482 return NULL; 1417 return NULL;
1483 1418
1484 size_t event_index; 1419 size_t event_index;
1485 TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index); 1420 TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index);
1486 if (trace_event && handle) { 1421 if (trace_event && handle) {
1487 MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_, 1422 MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_,
1488 event_index, handle); 1423 event_index, handle);
1489 } 1424 }
1490 return trace_event; 1425 return trace_event;
1491 } 1426 }
1492 1427
1493 void TraceLog::CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier) { 1428 void TraceLog::CheckIfBufferIsFullWhileLocked() {
1494 lock_.AssertAcquired(); 1429 lock_.AssertAcquired();
1495 if (!subtle::NoBarrier_Load(&buffer_is_full_) && logged_events_->IsFull()) { 1430 if (logged_events_->IsFull())
1496 subtle::NoBarrier_Store(&buffer_is_full_, 1431 SetDisabled();
1497 static_cast<subtle::AtomicWord>(1));
1498 notifier->AddNotificationWhileLocked(TRACE_BUFFER_FULL);
1499 }
1500 } 1432 }
1501 1433
1502 void TraceLog::SetEventCallback(EventCallback cb) { 1434 void TraceLog::SetEventCallback(EventCallback cb) {
1503 subtle::NoBarrier_Store(&event_callback_, 1435 subtle::NoBarrier_Store(&event_callback_,
1504 reinterpret_cast<subtle::AtomicWord>(cb)); 1436 reinterpret_cast<subtle::AtomicWord>(cb));
1505 }; 1437 };
1506 1438
1507 // Flush() works as the following: 1439 // Flush() works as the following:
1508 // 1. Flush() is called in threadA whose message loop is saved in 1440 // 1. Flush() is called in threadA whose message loop is saved in
1509 // flush_message_loop_proxy_; 1441 // flush_message_loop_proxy_;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 1528
1597 if (!CheckGeneration(generation)) 1529 if (!CheckGeneration(generation))
1598 return; 1530 return;
1599 1531
1600 { 1532 {
1601 AutoLock lock(lock_); 1533 AutoLock lock(lock_);
1602 1534
1603 previous_logged_events.swap(logged_events_); 1535 previous_logged_events.swap(logged_events_);
1604 logged_events_.reset(CreateTraceBuffer()); 1536 logged_events_.reset(CreateTraceBuffer());
1605 NextGeneration(); 1537 NextGeneration();
1606 subtle::NoBarrier_Store(&buffer_is_full_, 0);
1607 thread_message_loops_.clear(); 1538 thread_message_loops_.clear();
1608 1539
1609 flush_message_loop_proxy_ = NULL; 1540 flush_message_loop_proxy_ = NULL;
1610 flush_output_callback = flush_output_callback_; 1541 flush_output_callback = flush_output_callback_;
1611 flush_output_callback_.Reset(); 1542 flush_output_callback_.Reset();
1612 } 1543 }
1613 1544
1614 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 1545 ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(),
1615 flush_output_callback); 1546 flush_output_callback);
1616 } 1547 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 return handle; 1650 return handle;
1720 1651
1721 DCHECK(name); 1652 DCHECK(name);
1722 1653
1723 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 1654 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
1724 id ^= process_id_hash_; 1655 id ^= process_id_hash_;
1725 1656
1726 TimeTicks now = OffsetTimestamp(timestamp); 1657 TimeTicks now = OffsetTimestamp(timestamp);
1727 TimeTicks thread_now = ThreadNow(); 1658 TimeTicks thread_now = ThreadNow();
1728 1659
1729 NotificationHelper notifier(this);
1730
1731 ThreadLocalEventBuffer* thread_local_event_buffer = NULL; 1660 ThreadLocalEventBuffer* thread_local_event_buffer = NULL;
1732 // A ThreadLocalEventBuffer needs the message loop 1661 // A ThreadLocalEventBuffer needs the message loop
1733 // - to know when the thread exits; 1662 // - to know when the thread exits;
1734 // - to handle the final flush. 1663 // - to handle the final flush.
1735 // For a thread without a message loop or the message loop may be blocked, the 1664 // For a thread without a message loop or the message loop may be blocked, the
1736 // trace events will be added into the main buffer directly. 1665 // trace events will be added into the main buffer directly.
1737 if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) { 1666 if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) {
1738 thread_local_event_buffer = thread_local_event_buffer_.Get(); 1667 thread_local_event_buffer = thread_local_event_buffer_.Get();
1739 if (thread_local_event_buffer && 1668 if (thread_local_event_buffer &&
1740 !CheckGeneration(thread_local_event_buffer->generation())) { 1669 !CheckGeneration(thread_local_event_buffer->generation())) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 new_name) != existing_names.end(); 1706 new_name) != existing_names.end();
1778 if (!found) { 1707 if (!found) {
1779 existing_name->second.push_back(','); 1708 existing_name->second.push_back(',');
1780 existing_name->second.append(new_name); 1709 existing_name->second.append(new_name);
1781 } 1710 }
1782 } 1711 }
1783 } 1712 }
1784 } 1713 }
1785 1714
1786 TraceEvent* trace_event = NULL; 1715 TraceEvent* trace_event = NULL;
1787 if (!subtle::NoBarrier_Load(&buffer_is_full_)) { 1716 if (thread_local_event_buffer) {
1788 if (thread_local_event_buffer) { 1717 lock.EnsureReleased();
1789 lock.EnsureReleased(); 1718 trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
1790 trace_event = thread_local_event_buffer->AddTraceEvent(&notifier, 1719 } else {
1791 &handle); 1720 lock.EnsureAcquired();
1792 } else { 1721 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle);
1793 lock.EnsureAcquired(); 1722 }
1794 trace_event = AddEventToThreadSharedChunkWhileLocked(&notifier, &handle);
1795 }
1796 1723
1797 if (trace_event) { 1724 if (trace_event) {
1798 trace_event->Initialize(thread_id, now, thread_now, phase, 1725 trace_event->Initialize(thread_id, now, thread_now, phase,
1799 category_group_enabled, name, id, 1726 category_group_enabled, name, id,
1800 num_args, arg_names, arg_types, arg_values, 1727 num_args, arg_names, arg_types, arg_values,
1801 convertable_values, flags); 1728 convertable_values, flags);
1802 1729
1803 #if defined(OS_ANDROID) 1730 #if defined(OS_ANDROID)
1804 trace_event->SendToATrace(); 1731 trace_event->SendToATrace();
1805 #endif 1732 #endif
1806 }
1807 } 1733 }
1808 1734
1809 if (trace_options() & ECHO_TO_CONSOLE) { 1735 if (trace_options() & ECHO_TO_CONSOLE) {
1810 lock.EnsureAcquired(); 1736 lock.EnsureAcquired();
1811 OutputEventToConsoleWhileLocked( 1737 OutputEventToConsoleWhileLocked(
1812 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, 1738 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
1813 timestamp, trace_event); 1739 timestamp, trace_event);
1814 } 1740 }
1815 1741
1816 if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load( 1742 if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load(
1817 &watch_category_)) == category_group_enabled) { 1743 &watch_category_)) == category_group_enabled) {
1818 lock.EnsureAcquired(); 1744 lock.EnsureAcquired();
1819 if (watch_event_name_ == name) 1745 if (watch_event_name_ == name) {
1820 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); 1746 WatchEventCallback watch_event_callback_copy = watch_event_callback_;
1747 lock.EnsureReleased();
1748 if (!watch_event_callback_copy.is_null())
1749 watch_event_callback_copy.Run();
1750 }
1821 } 1751 }
1822 1752
1823 lock.EnsureReleased(); 1753 lock.EnsureReleased();
1824 EventCallback event_callback = reinterpret_cast<EventCallback>( 1754 EventCallback event_callback = reinterpret_cast<EventCallback>(
1825 subtle::NoBarrier_Load(&event_callback_)); 1755 subtle::NoBarrier_Load(&event_callback_));
1826 if (event_callback) { 1756 if (event_callback) {
1827 // TODO(wangxianzhu): Should send TRACE_EVENT_PHASE_COMPLETE directly to 1757 // TODO(wangxianzhu): Should send TRACE_EVENT_PHASE_COMPLETE directly to
1828 // clients if it is beneficial and feasible. 1758 // clients if it is beneficial and feasible.
1829 event_callback(now, 1759 event_callback(now,
1830 phase == TRACE_EVENT_PHASE_COMPLETE ? 1760 phase == TRACE_EVENT_PHASE_COMPLETE ?
1831 TRACE_EVENT_PHASE_BEGIN : phase, 1761 TRACE_EVENT_PHASE_BEGIN : phase,
1832 category_group_enabled, name, id, 1762 category_group_enabled, name, id,
1833 num_args, arg_names, arg_types, arg_values, 1763 num_args, arg_names, arg_types, arg_values,
1834 flags); 1764 flags);
1835 } 1765 }
1836 1766
1837 if (thread_local_event_buffer) 1767 if (thread_local_event_buffer)
1838 thread_local_event_buffer->ReportOverhead(now, thread_now, &notifier); 1768 thread_local_event_buffer->ReportOverhead(now, thread_now);
1839
1840 notifier.SendNotificationIfAny();
1841 1769
1842 return handle; 1770 return handle;
1843 } 1771 }
1844 1772
1845 // May be called when a COMPELETE event ends and the unfinished event has been 1773 // May be called when a COMPELETE event ends and the unfinished event has been
1846 // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL). 1774 // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL).
1847 void TraceLog::OutputEventToConsoleWhileLocked(unsigned char phase, 1775 void TraceLog::OutputEventToConsoleWhileLocked(unsigned char phase,
1848 const TimeTicks& timestamp, 1776 const TimeTicks& timestamp,
1849 TraceEvent* trace_event) { 1777 TraceEvent* trace_event) {
1850 // The caller should translate TRACE_EVENT_PHASE_COMPLETE to 1778 // The caller should translate TRACE_EVENT_PHASE_COMPLETE to
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 // TODO(wangxianzhu): Should send TRACE_EVENT_PHASE_COMPLETE directly to 1868 // TODO(wangxianzhu): Should send TRACE_EVENT_PHASE_COMPLETE directly to
1941 // clients if it is beneficial and feasible. 1869 // clients if it is beneficial and feasible.
1942 event_callback(now, TRACE_EVENT_PHASE_END, 1870 event_callback(now, TRACE_EVENT_PHASE_END,
1943 event_copy.category_group_enabled(), 1871 event_copy.category_group_enabled(),
1944 event_copy.name(), event_copy.id(), 1872 event_copy.name(), event_copy.id(),
1945 0, NULL, NULL, NULL, event_copy.flags()); 1873 0, NULL, NULL, NULL, event_copy.flags());
1946 } 1874 }
1947 } 1875 }
1948 1876
1949 void TraceLog::SetWatchEvent(const std::string& category_name, 1877 void TraceLog::SetWatchEvent(const std::string& category_name,
1950 const std::string& event_name) { 1878 const std::string& event_name,
1879 const WatchEventCallback& callback) {
1951 const unsigned char* category = GetCategoryGroupEnabled( 1880 const unsigned char* category = GetCategoryGroupEnabled(
1952 category_name.c_str()); 1881 category_name.c_str());
1953 AutoLock lock(lock_); 1882 AutoLock lock(lock_);
1954 subtle::NoBarrier_Store(&watch_category_, 1883 subtle::NoBarrier_Store(&watch_category_,
1955 reinterpret_cast<subtle::AtomicWord>(category)); 1884 reinterpret_cast<subtle::AtomicWord>(category));
1956 watch_event_name_ = event_name; 1885 watch_event_name_ = event_name;
1886 watch_event_callback_ = callback;
1957 } 1887 }
1958 1888
1959 void TraceLog::CancelWatchEvent() { 1889 void TraceLog::CancelWatchEvent() {
1960 AutoLock lock(lock_); 1890 AutoLock lock(lock_);
1961 subtle::NoBarrier_Store(&watch_category_, 0); 1891 subtle::NoBarrier_Store(&watch_category_, 0);
1962 watch_event_name_ = ""; 1892 watch_event_name_ = "";
1893 watch_event_callback_.Reset();
1963 } 1894 }
1964 1895
1965 void TraceLog::AddMetadataEventsWhileLocked() { 1896 void TraceLog::AddMetadataEventsWhileLocked() {
1966 lock_.AssertAcquired(); 1897 lock_.AssertAcquired();
1967 1898
1968 int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 1899 int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1969 if (process_sort_index_ != 0) { 1900 if (process_sort_index_ != 0) {
1970 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), 1901 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL),
1971 current_thread_id, 1902 current_thread_id,
1972 "process_sort_index", "sort_index", 1903 "process_sort_index", "sort_index",
1973 process_sort_index_); 1904 process_sort_index_);
1974 } 1905 }
1975 1906
1976 if (process_name_.size()) { 1907 if (process_name_.size()) {
1977 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), 1908 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL),
1978 current_thread_id, 1909 current_thread_id,
1979 "process_name", "name", 1910 "process_name", "name",
1980 process_name_); 1911 process_name_);
1981 } 1912 }
1982 1913
1983 if (process_labels_.size() > 0) { 1914 if (process_labels_.size() > 0) {
1984 std::vector<std::string> labels; 1915 std::vector<std::string> labels;
1985 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin(); 1916 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin();
1986 it != process_labels_.end(); 1917 it != process_labels_.end();
1987 it++) { 1918 it++) {
1988 labels.push_back(it->second); 1919 labels.push_back(it->second);
1989 } 1920 }
1990 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), 1921 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL),
1991 current_thread_id, 1922 current_thread_id,
1992 "process_labels", "labels", 1923 "process_labels", "labels",
1993 JoinString(labels, ',')); 1924 JoinString(labels, ','));
1994 } 1925 }
1995 1926
1996 // Thread sort indices. 1927 // Thread sort indices.
1997 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin(); 1928 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin();
1998 it != thread_sort_indices_.end(); 1929 it != thread_sort_indices_.end();
1999 it++) { 1930 it++) {
2000 if (it->second == 0) 1931 if (it->second == 0)
2001 continue; 1932 continue;
2002 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), 1933 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL),
2003 it->first, 1934 it->first,
2004 "thread_sort_index", "sort_index", 1935 "thread_sort_index", "sort_index",
2005 it->second); 1936 it->second);
2006 } 1937 }
2007 1938
2008 // Thread names. 1939 // Thread names.
2009 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); 1940 for(hash_map<int, std::string>::iterator it = thread_names_.begin();
2010 it != thread_names_.end(); 1941 it != thread_names_.end();
2011 it++) { 1942 it++) {
2012 if (it->second.empty()) 1943 if (it->second.empty())
2013 continue; 1944 continue;
2014 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, NULL), 1945 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL),
2015 it->first, 1946 it->first,
2016 "thread_name", "name", 1947 "thread_name", "name",
2017 it->second); 1948 it->second);
2018 } 1949 }
2019 } 1950 }
2020 1951
2021 void TraceLog::WaitSamplingEventForTesting() { 1952 void TraceLog::WaitSamplingEventForTesting() {
2022 if (!sampling_thread_) 1953 if (!sampling_thread_)
2023 return; 1954 return;
2024 sampling_thread_->WaitSamplingEventForTesting(); 1955 sampling_thread_->WaitSamplingEventForTesting();
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 0, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE); 2227 0, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE);
2297 } 2228 }
2298 } 2229 }
2299 2230
2300 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2231 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2301 if (*category_group_enabled_) 2232 if (*category_group_enabled_)
2302 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(event_handle_); 2233 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(event_handle_);
2303 } 2234 }
2304 2235
2305 } // namespace trace_event_internal 2236 } // namespace trace_event_internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698