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

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

Issue 109933006: Implement sampling profiler (chromium side change) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: All comments addressed 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 | 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 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 &&
dsinclair 2013/12/20 14:42:29 else if?
haraken 2013/12/25 07:52:31 Done.
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698