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 : mode_(DISABLED), | 1110 : enabled_(false), |
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), RECORDING_MODE, ECHO_TO_CONSOLE); | 1156 SetEnabled(CategoryFilter(filter), 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 (mode_ == RECORDING_MODE && | 1195 if (enabled_ && category_filter_.IsCategoryGroupEnabled(category_group)) |
1196 category_filter_.IsCategoryGroupEnabled(category_group)) | |
1197 enabled_flag |= ENABLED_FOR_RECORDING; | 1196 enabled_flag |= ENABLED_FOR_RECORDING; |
1198 else if (mode_ == MONITORING_MODE && | |
1199 category_filter_.IsCategoryGroupEnabled(category_group)) | |
1200 enabled_flag |= ENABLED_FOR_MONITORING; | |
1201 if (event_callback_ && | 1197 if (event_callback_ && |
1202 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) | 1198 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) |
1203 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | 1199 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; |
1204 g_category_group_enabled[category_index] = enabled_flag; | 1200 g_category_group_enabled[category_index] = enabled_flag; |
1205 } | 1201 } |
1206 | 1202 |
1207 void TraceLog::UpdateCategoryGroupEnabledFlags() { | 1203 void TraceLog::UpdateCategoryGroupEnabledFlags() { |
1208 for (int i = 0; i < g_category_index; i++) | 1204 for (int i = 0; i < g_category_index; i++) |
1209 UpdateCategoryGroupEnabledFlag(i); | 1205 UpdateCategoryGroupEnabledFlag(i); |
1210 } | 1206 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 void TraceLog::GetKnownCategoryGroups( | 1249 void TraceLog::GetKnownCategoryGroups( |
1254 std::vector<std::string>* category_groups) { | 1250 std::vector<std::string>* category_groups) { |
1255 AutoLock lock(lock_); | 1251 AutoLock lock(lock_); |
1256 category_groups->push_back( | 1252 category_groups->push_back( |
1257 g_category_groups[g_category_trace_event_overhead]); | 1253 g_category_groups[g_category_trace_event_overhead]); |
1258 for (int i = g_num_builtin_categories; i < g_category_index; i++) | 1254 for (int i = g_num_builtin_categories; i < g_category_index; i++) |
1259 category_groups->push_back(g_category_groups[i]); | 1255 category_groups->push_back(g_category_groups[i]); |
1260 } | 1256 } |
1261 | 1257 |
1262 void TraceLog::SetEnabled(const CategoryFilter& category_filter, | 1258 void TraceLog::SetEnabled(const CategoryFilter& category_filter, |
1263 Mode mode, | |
1264 Options options) { | 1259 Options options) { |
1265 std::vector<EnabledStateObserver*> observer_list; | 1260 std::vector<EnabledStateObserver*> observer_list; |
1266 { | 1261 { |
1267 AutoLock lock(lock_); | 1262 AutoLock lock(lock_); |
1268 | 1263 |
1269 // Can't enable tracing when Flush() is in progress. | 1264 // Can't enable tracing when Flush() is in progress. |
1270 DCHECK(!flush_message_loop_proxy_.get()); | 1265 DCHECK(!flush_message_loop_proxy_.get()); |
1271 | 1266 |
1272 Options old_options = trace_options(); | 1267 Options old_options = trace_options(); |
1273 | 1268 |
1274 if (IsEnabled()) { | 1269 if (enabled_) { |
1275 if (options != old_options) { | 1270 if (options != old_options) { |
1276 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | 1271 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
1277 << "set of options."; | 1272 << "set of options."; |
1278 } | 1273 } |
1279 | 1274 |
1280 if (mode != mode_) { | |
1281 DLOG(ERROR) << "Attemting to re-enable tracing with a different mode."; | |
1282 } | |
1283 | |
1284 category_filter_.Merge(category_filter); | 1275 category_filter_.Merge(category_filter); |
1285 UpdateCategoryGroupEnabledFlags(); | 1276 UpdateCategoryGroupEnabledFlags(); |
1286 return; | 1277 return; |
1287 } | 1278 } |
1288 | 1279 |
1289 if (dispatching_to_observer_list_) { | 1280 if (dispatching_to_observer_list_) { |
1290 DLOG(ERROR) << | 1281 DLOG(ERROR) << |
1291 "Cannot manipulate TraceLog::Enabled state from an observer."; | 1282 "Cannot manipulate TraceLog::Enabled state from an observer."; |
1292 return; | 1283 return; |
1293 } | 1284 } |
1294 | 1285 |
1295 mode_ = mode; | 1286 enabled_ = true; |
1296 | 1287 |
1297 if (options != old_options) { | 1288 if (options != old_options) { |
1298 subtle::NoBarrier_Store(&trace_options_, options); | 1289 subtle::NoBarrier_Store(&trace_options_, options); |
1299 UseNextTraceBuffer(); | 1290 UseNextTraceBuffer(); |
1300 } | 1291 } |
1301 | 1292 |
1302 num_traces_recorded_++; | 1293 num_traces_recorded_++; |
1303 | 1294 |
1304 category_filter_ = CategoryFilter(category_filter); | 1295 category_filter_ = CategoryFilter(category_filter); |
1305 UpdateCategoryGroupEnabledFlags(); | 1296 UpdateCategoryGroupEnabledFlags(); |
1306 | 1297 |
1307 if (options & ENABLE_SAMPLING) { | 1298 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { |
1308 sampling_thread_.reset(new TraceSamplingThread); | 1299 sampling_thread_.reset(new TraceSamplingThread); |
1309 sampling_thread_->RegisterSampleBucket( | 1300 sampling_thread_->RegisterSampleBucket( |
1310 &g_trace_state[0], | 1301 &g_trace_state[0], |
1311 "bucket0", | 1302 "bucket0", |
1312 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1303 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
1313 sampling_thread_->RegisterSampleBucket( | 1304 sampling_thread_->RegisterSampleBucket( |
1314 &g_trace_state[1], | 1305 &g_trace_state[1], |
1315 "bucket1", | 1306 "bucket1", |
1316 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1307 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
1317 sampling_thread_->RegisterSampleBucket( | 1308 sampling_thread_->RegisterSampleBucket( |
(...skipping 25 matching lines...) Expand all Loading... |
1343 } | 1334 } |
1344 | 1335 |
1345 void TraceLog::SetDisabled() { | 1336 void TraceLog::SetDisabled() { |
1346 AutoLock lock(lock_); | 1337 AutoLock lock(lock_); |
1347 SetDisabledWhileLocked(); | 1338 SetDisabledWhileLocked(); |
1348 } | 1339 } |
1349 | 1340 |
1350 void TraceLog::SetDisabledWhileLocked() { | 1341 void TraceLog::SetDisabledWhileLocked() { |
1351 lock_.AssertAcquired(); | 1342 lock_.AssertAcquired(); |
1352 | 1343 |
1353 if (!IsEnabled()) | 1344 if (!enabled_) |
1354 return; | 1345 return; |
1355 | 1346 |
1356 if (dispatching_to_observer_list_) { | 1347 if (dispatching_to_observer_list_) { |
1357 DLOG(ERROR) | 1348 DLOG(ERROR) |
1358 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 1349 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
1359 return; | 1350 return; |
1360 } | 1351 } |
1361 | 1352 |
1362 mode_ = DISABLED; | 1353 enabled_ = false; |
1363 | 1354 |
1364 if (sampling_thread_.get()) { | 1355 if (sampling_thread_.get()) { |
1365 base::ThreadRestrictions::SetIOAllowed(true); | |
1366 | |
1367 // Stop the sampling thread. | 1356 // Stop the sampling thread. |
1368 sampling_thread_->Stop(); | 1357 sampling_thread_->Stop(); |
1369 lock_.Release(); | 1358 lock_.Release(); |
1370 PlatformThread::Join(sampling_thread_handle_); | 1359 PlatformThread::Join(sampling_thread_handle_); |
1371 lock_.Acquire(); | 1360 lock_.Acquire(); |
1372 sampling_thread_handle_ = PlatformThreadHandle(); | 1361 sampling_thread_handle_ = PlatformThreadHandle(); |
1373 sampling_thread_.reset(); | 1362 sampling_thread_.reset(); |
1374 | |
1375 base::ThreadRestrictions::SetIOAllowed(false); | |
1376 } | 1363 } |
1377 | 1364 |
1378 category_filter_.Clear(); | 1365 category_filter_.Clear(); |
1379 subtle::NoBarrier_Store(&watch_category_, 0); | 1366 subtle::NoBarrier_Store(&watch_category_, 0); |
1380 watch_event_name_ = ""; | 1367 watch_event_name_ = ""; |
1381 UpdateCategoryGroupEnabledFlags(); | 1368 UpdateCategoryGroupEnabledFlags(); |
1382 AddMetadataEventsWhileLocked(); | 1369 AddMetadataEventsWhileLocked(); |
1383 | 1370 |
1384 dispatching_to_observer_list_ = true; | 1371 dispatching_to_observer_list_ = true; |
1385 std::vector<EnabledStateObserver*> observer_list = | 1372 std::vector<EnabledStateObserver*> observer_list = |
1386 enabled_state_observer_list_; | 1373 enabled_state_observer_list_; |
1387 | 1374 |
1388 { | 1375 { |
1389 // Dispatch to observers outside the lock in case the observer triggers a | 1376 // Dispatch to observers outside the lock in case the observer triggers a |
1390 // trace event. | 1377 // trace event. |
1391 AutoUnlock unlock(lock_); | 1378 AutoUnlock unlock(lock_); |
1392 for (size_t i = 0; i < observer_list.size(); ++i) | 1379 for (size_t i = 0; i < observer_list.size(); ++i) |
1393 observer_list[i]->OnTraceLogDisabled(); | 1380 observer_list[i]->OnTraceLogDisabled(); |
1394 } | 1381 } |
1395 dispatching_to_observer_list_ = false; | 1382 dispatching_to_observer_list_ = false; |
1396 } | 1383 } |
1397 | 1384 |
1398 int TraceLog::GetNumTracesRecorded() { | 1385 int TraceLog::GetNumTracesRecorded() { |
1399 AutoLock lock(lock_); | 1386 AutoLock lock(lock_); |
1400 if (!IsEnabled()) | 1387 if (!enabled_) |
1401 return -1; | 1388 return -1; |
1402 return num_traces_recorded_; | 1389 return num_traces_recorded_; |
1403 } | 1390 } |
1404 | 1391 |
1405 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { | 1392 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { |
1406 enabled_state_observer_list_.push_back(listener); | 1393 enabled_state_observer_list_.push_back(listener); |
1407 } | 1394 } |
1408 | 1395 |
1409 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { | 1396 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { |
1410 std::vector<EnabledStateObserver*>::iterator it = | 1397 std::vector<EnabledStateObserver*>::iterator it = |
(...skipping 20 matching lines...) Expand all Loading... |
1431 | 1418 |
1432 bool TraceLog::BufferIsFull() const { | 1419 bool TraceLog::BufferIsFull() const { |
1433 AutoLock lock(lock_); | 1420 AutoLock lock(lock_); |
1434 return logged_events_->IsFull(); | 1421 return logged_events_->IsFull(); |
1435 } | 1422 } |
1436 | 1423 |
1437 TraceBuffer* TraceLog::CreateTraceBuffer() { | 1424 TraceBuffer* TraceLog::CreateTraceBuffer() { |
1438 Options options = trace_options(); | 1425 Options options = trace_options(); |
1439 if (options & RECORD_CONTINUOUSLY) | 1426 if (options & RECORD_CONTINUOUSLY) |
1440 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); | 1427 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); |
1441 else if ((options & ENABLE_SAMPLING) && mode_ == MONITORING_MODE) | 1428 else if (options & MONITOR_SAMPLING) |
1442 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); | 1429 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); |
1443 else if (options & ECHO_TO_CONSOLE) | 1430 else if (options & ECHO_TO_CONSOLE) |
1444 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); | 1431 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); |
1445 return new TraceBufferVector(); | 1432 return new TraceBufferVector(); |
1446 } | 1433 } |
1447 | 1434 |
1448 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( | 1435 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( |
1449 TraceEventHandle* handle, bool check_buffer_is_full) { | 1436 TraceEventHandle* handle, bool check_buffer_is_full) { |
1450 lock_.AssertAcquired(); | 1437 lock_.AssertAcquired(); |
1451 | 1438 |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 if (!found) { | 1762 if (!found) { |
1776 if (existing_names.size()) | 1763 if (existing_names.size()) |
1777 existing_name->second.push_back(','); | 1764 existing_name->second.push_back(','); |
1778 existing_name->second.append(new_name); | 1765 existing_name->second.append(new_name); |
1779 } | 1766 } |
1780 } | 1767 } |
1781 } | 1768 } |
1782 } | 1769 } |
1783 | 1770 |
1784 std::string console_message; | 1771 std::string console_message; |
1785 if (*category_group_enabled & | 1772 if ((*category_group_enabled & ENABLED_FOR_RECORDING)) { |
1786 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { | |
1787 OptionalAutoLock lock(lock_); | 1773 OptionalAutoLock lock(lock_); |
1788 | 1774 |
1789 TraceEvent* trace_event = NULL; | 1775 TraceEvent* trace_event = NULL; |
1790 if (thread_local_event_buffer) { | 1776 if (thread_local_event_buffer) { |
1791 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1777 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
1792 } else { | 1778 } else { |
1793 lock.EnsureAcquired(); | 1779 lock.EnsureAcquired(); |
1794 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1780 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
1795 } | 1781 } |
1796 | 1782 |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2326 } | 2312 } |
2327 | 2313 |
2328 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2314 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
2329 if (*category_group_enabled_) { | 2315 if (*category_group_enabled_) { |
2330 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2316 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
2331 name_, event_handle_); | 2317 name_, event_handle_); |
2332 } | 2318 } |
2333 } | 2319 } |
2334 | 2320 |
2335 } // namespace trace_event_internal | 2321 } // namespace trace_event_internal |
OLD | NEW |