| OLD | NEW |
| 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 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { | 1087 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { |
| 1088 delete this; | 1088 delete this; |
| 1089 } | 1089 } |
| 1090 | 1090 |
| 1091 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { | 1091 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { |
| 1092 if (!chunk_) | 1092 if (!chunk_) |
| 1093 return; | 1093 return; |
| 1094 | 1094 |
| 1095 trace_log_->lock_.AssertAcquired(); | 1095 trace_log_->lock_.AssertAcquired(); |
| 1096 if (trace_log_->CheckGeneration(generation_)) { | 1096 if (trace_log_->CheckGeneration(generation_)) { |
| 1097 // Return the chunk to the buffer only if the generation matches, | 1097 // Return the chunk to the buffer only if the generation matches. |
| 1098 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); | 1098 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); |
| 1099 } | 1099 } |
| 1100 // Otherwise this method may be called from the destructor, or TraceLog will | 1100 // Otherwise this method may be called from the destructor, or TraceLog will |
| 1101 // find the generation mismatch and delete this buffer soon. | 1101 // find the generation mismatch and delete this buffer soon. |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 // static | 1104 // static |
| 1105 TraceLog* TraceLog::GetInstance() { | 1105 TraceLog* TraceLog::GetInstance() { |
| 1106 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); | 1106 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 TraceLog::TraceLog() | 1109 TraceLog::TraceLog() |
| 1110 : enabled_(false), | 1110 : mode_(DISABLED), |
| 1111 num_traces_recorded_(0), | 1111 num_traces_recorded_(0), |
| 1112 event_callback_(0), | 1112 event_callback_(0), |
| 1113 dispatching_to_observer_list_(false), | 1113 dispatching_to_observer_list_(false), |
| 1114 process_sort_index_(0), | 1114 process_sort_index_(0), |
| 1115 process_id_hash_(0), | 1115 process_id_hash_(0), |
| 1116 process_id_(0), | 1116 process_id_(0), |
| 1117 watch_category_(0), | 1117 watch_category_(0), |
| 1118 trace_options_(RECORD_UNTIL_FULL), | 1118 trace_options_(RECORD_UNTIL_FULL), |
| 1119 sampling_thread_handle_(0), | 1119 sampling_thread_handle_(0), |
| 1120 category_filter_(CategoryFilter::kDefaultCategoryFilterString), | 1120 category_filter_(CategoryFilter::kDefaultCategoryFilterString), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1146 switches::kTraceToConsole); | 1146 switches::kTraceToConsole); |
| 1147 if (filter.empty()) { | 1147 if (filter.empty()) { |
| 1148 filter = kEchoToConsoleCategoryFilter; | 1148 filter = kEchoToConsoleCategoryFilter; |
| 1149 } else { | 1149 } else { |
| 1150 filter.append(","); | 1150 filter.append(","); |
| 1151 filter.append(kEchoToConsoleCategoryFilter); | 1151 filter.append(kEchoToConsoleCategoryFilter); |
| 1152 } | 1152 } |
| 1153 | 1153 |
| 1154 LOG(ERROR) << "Start " << switches::kTraceToConsole | 1154 LOG(ERROR) << "Start " << switches::kTraceToConsole |
| 1155 << " with CategoryFilter '" << filter << "'."; | 1155 << " with CategoryFilter '" << filter << "'."; |
| 1156 SetEnabled(CategoryFilter(filter), ECHO_TO_CONSOLE); | 1156 SetEnabled(CategoryFilter(filter), RECORDING_MODE, ECHO_TO_CONSOLE); |
| 1157 } | 1157 } |
| 1158 #endif | 1158 #endif |
| 1159 | 1159 |
| 1160 logged_events_.reset(CreateTraceBuffer()); | 1160 logged_events_.reset(CreateTraceBuffer()); |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 TraceLog::~TraceLog() { | 1163 TraceLog::~TraceLog() { |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 const unsigned char* TraceLog::GetCategoryGroupEnabled( | 1166 const unsigned char* TraceLog::GetCategoryGroupEnabled( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1185 g_category_group_enabled + MAX_CATEGORY_GROUPS)) << | 1185 g_category_group_enabled + MAX_CATEGORY_GROUPS)) << |
| 1186 "out of bounds category pointer"; | 1186 "out of bounds category pointer"; |
| 1187 uintptr_t category_index = | 1187 uintptr_t category_index = |
| 1188 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); | 1188 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); |
| 1189 return g_category_groups[category_index]; | 1189 return g_category_groups[category_index]; |
| 1190 } | 1190 } |
| 1191 | 1191 |
| 1192 void TraceLog::UpdateCategoryGroupEnabledFlag(int category_index) { | 1192 void TraceLog::UpdateCategoryGroupEnabledFlag(int category_index) { |
| 1193 unsigned char enabled_flag = 0; | 1193 unsigned char enabled_flag = 0; |
| 1194 const char* category_group = g_category_groups[category_index]; | 1194 const char* category_group = g_category_groups[category_index]; |
| 1195 if (enabled_ && category_filter_.IsCategoryGroupEnabled(category_group)) | 1195 if (mode_ == RECORDING_MODE && |
| 1196 category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1196 enabled_flag |= ENABLED_FOR_RECORDING; | 1197 enabled_flag |= ENABLED_FOR_RECORDING; |
| 1198 if (mode_ == MONITORING_MODE && |
| 1199 category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1200 enabled_flag |= ENABLED_FOR_MONITORING; |
| 1197 if (event_callback_ && | 1201 if (event_callback_ && |
| 1198 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) | 1202 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1199 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | 1203 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; |
| 1200 g_category_group_enabled[category_index] = enabled_flag; | 1204 g_category_group_enabled[category_index] = enabled_flag; |
| 1201 } | 1205 } |
| 1202 | 1206 |
| 1203 void TraceLog::UpdateCategoryGroupEnabledFlags() { | 1207 void TraceLog::UpdateCategoryGroupEnabledFlags() { |
| 1204 for (int i = 0; i < g_category_index; i++) | 1208 for (int i = 0; i < g_category_index; i++) |
| 1205 UpdateCategoryGroupEnabledFlag(i); | 1209 UpdateCategoryGroupEnabledFlag(i); |
| 1206 } | 1210 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 void TraceLog::GetKnownCategoryGroups( | 1253 void TraceLog::GetKnownCategoryGroups( |
| 1250 std::vector<std::string>* category_groups) { | 1254 std::vector<std::string>* category_groups) { |
| 1251 AutoLock lock(lock_); | 1255 AutoLock lock(lock_); |
| 1252 category_groups->push_back( | 1256 category_groups->push_back( |
| 1253 g_category_groups[g_category_trace_event_overhead]); | 1257 g_category_groups[g_category_trace_event_overhead]); |
| 1254 for (int i = g_num_builtin_categories; i < g_category_index; i++) | 1258 for (int i = g_num_builtin_categories; i < g_category_index; i++) |
| 1255 category_groups->push_back(g_category_groups[i]); | 1259 category_groups->push_back(g_category_groups[i]); |
| 1256 } | 1260 } |
| 1257 | 1261 |
| 1258 void TraceLog::SetEnabled(const CategoryFilter& category_filter, | 1262 void TraceLog::SetEnabled(const CategoryFilter& category_filter, |
| 1263 Mode mode, |
| 1259 Options options) { | 1264 Options options) { |
| 1260 std::vector<EnabledStateObserver*> observer_list; | 1265 std::vector<EnabledStateObserver*> observer_list; |
| 1261 { | 1266 { |
| 1262 AutoLock lock(lock_); | 1267 AutoLock lock(lock_); |
| 1263 | 1268 |
| 1264 // Can't enable tracing when Flush() is in progress. | 1269 // Can't enable tracing when Flush() is in progress. |
| 1265 DCHECK(!flush_message_loop_proxy_.get()); | 1270 DCHECK(!flush_message_loop_proxy_.get()); |
| 1266 | 1271 |
| 1267 Options old_options = trace_options(); | 1272 Options old_options = trace_options(); |
| 1268 | 1273 |
| 1269 if (enabled_) { | 1274 if (IsEnabled()) { |
| 1270 if (options != old_options) { | 1275 if (options != old_options) { |
| 1271 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | 1276 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
| 1272 << "set of options."; | 1277 << "set of options."; |
| 1273 } | 1278 } |
| 1274 | 1279 |
| 1280 if (mode != mode_) { |
| 1281 DLOG(ERROR) << "Attemting to re-enable tracing with a different mode."; |
| 1282 } |
| 1283 |
| 1275 category_filter_.Merge(category_filter); | 1284 category_filter_.Merge(category_filter); |
| 1276 UpdateCategoryGroupEnabledFlags(); | 1285 UpdateCategoryGroupEnabledFlags(); |
| 1277 return; | 1286 return; |
| 1278 } | 1287 } |
| 1279 | 1288 |
| 1280 if (dispatching_to_observer_list_) { | 1289 if (dispatching_to_observer_list_) { |
| 1281 DLOG(ERROR) << | 1290 DLOG(ERROR) << |
| 1282 "Cannot manipulate TraceLog::Enabled state from an observer."; | 1291 "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 1283 return; | 1292 return; |
| 1284 } | 1293 } |
| 1285 | 1294 |
| 1286 enabled_ = true; | 1295 mode_ = mode; |
| 1287 | 1296 |
| 1288 if (options != old_options) { | 1297 if (options != old_options) { |
| 1289 subtle::NoBarrier_Store(&trace_options_, options); | 1298 subtle::NoBarrier_Store(&trace_options_, options); |
| 1290 UseNextTraceBuffer(); | 1299 UseNextTraceBuffer(); |
| 1291 } | 1300 } |
| 1292 | 1301 |
| 1293 num_traces_recorded_++; | 1302 num_traces_recorded_++; |
| 1294 | 1303 |
| 1295 category_filter_ = CategoryFilter(category_filter); | 1304 category_filter_ = CategoryFilter(category_filter); |
| 1296 UpdateCategoryGroupEnabledFlags(); | 1305 UpdateCategoryGroupEnabledFlags(); |
| 1297 | 1306 |
| 1298 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { | 1307 if (options & ENABLE_SAMPLING) { |
| 1299 sampling_thread_.reset(new TraceSamplingThread); | 1308 sampling_thread_.reset(new TraceSamplingThread); |
| 1300 sampling_thread_->RegisterSampleBucket( | 1309 sampling_thread_->RegisterSampleBucket( |
| 1301 &g_trace_state[0], | 1310 &g_trace_state[0], |
| 1302 "bucket0", | 1311 "bucket0", |
| 1303 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1312 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
| 1304 sampling_thread_->RegisterSampleBucket( | 1313 sampling_thread_->RegisterSampleBucket( |
| 1305 &g_trace_state[1], | 1314 &g_trace_state[1], |
| 1306 "bucket1", | 1315 "bucket1", |
| 1307 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1316 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
| 1308 sampling_thread_->RegisterSampleBucket( | 1317 sampling_thread_->RegisterSampleBucket( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1334 } | 1343 } |
| 1335 | 1344 |
| 1336 void TraceLog::SetDisabled() { | 1345 void TraceLog::SetDisabled() { |
| 1337 AutoLock lock(lock_); | 1346 AutoLock lock(lock_); |
| 1338 SetDisabledWhileLocked(); | 1347 SetDisabledWhileLocked(); |
| 1339 } | 1348 } |
| 1340 | 1349 |
| 1341 void TraceLog::SetDisabledWhileLocked() { | 1350 void TraceLog::SetDisabledWhileLocked() { |
| 1342 lock_.AssertAcquired(); | 1351 lock_.AssertAcquired(); |
| 1343 | 1352 |
| 1344 if (!enabled_) | 1353 if (!IsEnabled()) |
| 1345 return; | 1354 return; |
| 1346 | 1355 |
| 1347 if (dispatching_to_observer_list_) { | 1356 if (dispatching_to_observer_list_) { |
| 1348 DLOG(ERROR) | 1357 DLOG(ERROR) |
| 1349 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 1358 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 1350 return; | 1359 return; |
| 1351 } | 1360 } |
| 1352 | 1361 |
| 1353 enabled_ = false; | 1362 mode_ = DISABLED; |
| 1354 | 1363 |
| 1355 if (sampling_thread_.get()) { | 1364 if (sampling_thread_.get()) { |
| 1356 // Stop the sampling thread. | 1365 // Stop the sampling thread. |
| 1357 sampling_thread_->Stop(); | 1366 sampling_thread_->Stop(); |
| 1358 lock_.Release(); | 1367 lock_.Release(); |
| 1359 PlatformThread::Join(sampling_thread_handle_); | 1368 PlatformThread::Join(sampling_thread_handle_); |
| 1360 lock_.Acquire(); | 1369 lock_.Acquire(); |
| 1361 sampling_thread_handle_ = PlatformThreadHandle(); | 1370 sampling_thread_handle_ = PlatformThreadHandle(); |
| 1362 sampling_thread_.reset(); | 1371 sampling_thread_.reset(); |
| 1363 } | 1372 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1377 // trace event. | 1386 // trace event. |
| 1378 AutoUnlock unlock(lock_); | 1387 AutoUnlock unlock(lock_); |
| 1379 for (size_t i = 0; i < observer_list.size(); ++i) | 1388 for (size_t i = 0; i < observer_list.size(); ++i) |
| 1380 observer_list[i]->OnTraceLogDisabled(); | 1389 observer_list[i]->OnTraceLogDisabled(); |
| 1381 } | 1390 } |
| 1382 dispatching_to_observer_list_ = false; | 1391 dispatching_to_observer_list_ = false; |
| 1383 } | 1392 } |
| 1384 | 1393 |
| 1385 int TraceLog::GetNumTracesRecorded() { | 1394 int TraceLog::GetNumTracesRecorded() { |
| 1386 AutoLock lock(lock_); | 1395 AutoLock lock(lock_); |
| 1387 if (!enabled_) | 1396 if (!IsEnabled()) |
| 1388 return -1; | 1397 return -1; |
| 1389 return num_traces_recorded_; | 1398 return num_traces_recorded_; |
| 1390 } | 1399 } |
| 1391 | 1400 |
| 1392 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { | 1401 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { |
| 1393 enabled_state_observer_list_.push_back(listener); | 1402 enabled_state_observer_list_.push_back(listener); |
| 1394 } | 1403 } |
| 1395 | 1404 |
| 1396 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { | 1405 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { |
| 1397 std::vector<EnabledStateObserver*>::iterator it = | 1406 std::vector<EnabledStateObserver*>::iterator it = |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1418 | 1427 |
| 1419 bool TraceLog::BufferIsFull() const { | 1428 bool TraceLog::BufferIsFull() const { |
| 1420 AutoLock lock(lock_); | 1429 AutoLock lock(lock_); |
| 1421 return logged_events_->IsFull(); | 1430 return logged_events_->IsFull(); |
| 1422 } | 1431 } |
| 1423 | 1432 |
| 1424 TraceBuffer* TraceLog::CreateTraceBuffer() { | 1433 TraceBuffer* TraceLog::CreateTraceBuffer() { |
| 1425 Options options = trace_options(); | 1434 Options options = trace_options(); |
| 1426 if (options & RECORD_CONTINUOUSLY) | 1435 if (options & RECORD_CONTINUOUSLY) |
| 1427 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); | 1436 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); |
| 1428 else if (options & MONITOR_SAMPLING) | 1437 else if ((options & ENABLE_SAMPLING) && mode_ == MONITORING_MODE) |
| 1429 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); | 1438 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); |
| 1430 else if (options & ECHO_TO_CONSOLE) | 1439 else if (options & ECHO_TO_CONSOLE) |
| 1431 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); | 1440 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); |
| 1432 return new TraceBufferVector(); | 1441 return new TraceBufferVector(); |
| 1433 } | 1442 } |
| 1434 | 1443 |
| 1435 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( | 1444 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( |
| 1436 TraceEventHandle* handle, bool check_buffer_is_full) { | 1445 TraceEventHandle* handle, bool check_buffer_is_full) { |
| 1437 lock_.AssertAcquired(); | 1446 lock_.AssertAcquired(); |
| 1438 | 1447 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 if (!found) { | 1771 if (!found) { |
| 1763 if (existing_names.size()) | 1772 if (existing_names.size()) |
| 1764 existing_name->second.push_back(','); | 1773 existing_name->second.push_back(','); |
| 1765 existing_name->second.append(new_name); | 1774 existing_name->second.append(new_name); |
| 1766 } | 1775 } |
| 1767 } | 1776 } |
| 1768 } | 1777 } |
| 1769 } | 1778 } |
| 1770 | 1779 |
| 1771 std::string console_message; | 1780 std::string console_message; |
| 1772 if ((*category_group_enabled & ENABLED_FOR_RECORDING)) { | 1781 if (*category_group_enabled & |
| 1782 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { |
| 1773 OptionalAutoLock lock(lock_); | 1783 OptionalAutoLock lock(lock_); |
| 1774 | 1784 |
| 1775 TraceEvent* trace_event = NULL; | 1785 TraceEvent* trace_event = NULL; |
| 1776 if (thread_local_event_buffer) { | 1786 if (thread_local_event_buffer) { |
| 1777 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1787 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
| 1778 } else { | 1788 } else { |
| 1779 lock.EnsureAcquired(); | 1789 lock.EnsureAcquired(); |
| 1780 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1790 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
| 1781 } | 1791 } |
| 1782 | 1792 |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2312 } | 2322 } |
| 2313 | 2323 |
| 2314 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2324 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2315 if (*category_group_enabled_) { | 2325 if (*category_group_enabled_) { |
| 2316 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2326 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
| 2317 name_, event_handle_); | 2327 name_, event_handle_); |
| 2318 } | 2328 } |
| 2319 } | 2329 } |
| 2320 | 2330 |
| 2321 } // namespace trace_event_internal | 2331 } // namespace trace_event_internal |
| OLD | NEW |