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 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 int thread_id, | 1171 int thread_id, |
1172 const TimeTicks& timestamp, | 1172 const TimeTicks& timestamp, |
1173 int num_args, | 1173 int num_args, |
1174 const char** arg_names, | 1174 const char** arg_names, |
1175 const unsigned char* arg_types, | 1175 const unsigned char* arg_types, |
1176 const unsigned long long* arg_values, | 1176 const unsigned long long* arg_values, |
1177 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 1177 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
1178 unsigned char flags) { | 1178 unsigned char flags) { |
1179 DCHECK(name); | 1179 DCHECK(name); |
1180 | 1180 |
1181 TimeDelta duration; | |
1182 if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_CONSOLE) { | |
1183 duration = timestamp - thread_event_start_times_[thread_id].top(); | |
1184 thread_event_start_times_[thread_id].pop(); | |
1185 } | |
1186 | |
1187 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) | 1181 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) |
1188 id ^= process_id_hash_; | 1182 id ^= process_id_hash_; |
1189 | 1183 |
1190 #if defined(OS_ANDROID) | 1184 #if defined(OS_ANDROID) |
1191 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, | 1185 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, |
1192 num_args, arg_names, arg_types, arg_values, convertable_values, | 1186 num_args, arg_names, arg_types, arg_values, convertable_values, |
1193 flags); | 1187 flags); |
1194 #endif | 1188 #endif |
1195 | 1189 |
| 1190 if (!IsCategoryGroupEnabled(category_group_enabled)) |
| 1191 return; |
| 1192 |
1196 TimeTicks now = timestamp - time_offset_; | 1193 TimeTicks now = timestamp - time_offset_; |
1197 EventCallback event_callback_copy; | 1194 EventCallback event_callback_copy; |
1198 | 1195 |
1199 NotificationHelper notifier(this); | 1196 NotificationHelper notifier(this); |
1200 | 1197 |
1201 do { | 1198 // Check and update the current thread name only if the event is for the |
1202 AutoLock lock(lock_); | 1199 // current thread to avoid locks in most cases. |
1203 if (!IsCategoryGroupEnabled(category_group_enabled)) | 1200 if (thread_id == static_cast<int>(PlatformThread::CurrentId())) { |
1204 return; | |
1205 | |
1206 event_callback_copy = event_callback_; | |
1207 if (logged_events_->IsFull()) | |
1208 break; | |
1209 | |
1210 const char* new_name = ThreadIdNameManager::GetInstance()-> | 1201 const char* new_name = ThreadIdNameManager::GetInstance()-> |
1211 GetName(thread_id); | 1202 GetName(thread_id); |
1212 // Check if the thread name has been set or changed since the previous | 1203 // Check if the thread name has been set or changed since the previous |
1213 // call (if any), but don't bother if the new name is empty. Note this will | 1204 // call (if any), but don't bother if the new name is empty. Note this will |
1214 // not detect a thread name change within the same char* buffer address: we | 1205 // not detect a thread name change within the same char* buffer address: we |
1215 // favor common case performance over corner case correctness. | 1206 // favor common case performance over corner case correctness. |
1216 if (new_name != g_current_thread_name.Get().Get() && | 1207 if (new_name != g_current_thread_name.Get().Get() && |
1217 new_name && *new_name) { | 1208 new_name && *new_name) { |
1218 g_current_thread_name.Get().Set(new_name); | 1209 g_current_thread_name.Get().Set(new_name); |
1219 | 1210 |
| 1211 AutoLock lock(lock_); |
1220 hash_map<int, std::string>::iterator existing_name = | 1212 hash_map<int, std::string>::iterator existing_name = |
1221 thread_names_.find(thread_id); | 1213 thread_names_.find(thread_id); |
1222 if (existing_name == thread_names_.end()) { | 1214 if (existing_name == thread_names_.end()) { |
1223 // This is a new thread id, and a new name. | 1215 // This is a new thread id, and a new name. |
1224 thread_names_[thread_id] = new_name; | 1216 thread_names_[thread_id] = new_name; |
1225 } else { | 1217 } else { |
1226 // This is a thread id that we've seen before, but potentially with a | 1218 // This is a thread id that we've seen before, but potentially with a |
1227 // new name. | 1219 // new name. |
1228 std::vector<StringPiece> existing_names; | 1220 std::vector<StringPiece> existing_names; |
1229 Tokenize(existing_name->second, ",", &existing_names); | 1221 Tokenize(existing_name->second, ",", &existing_names); |
1230 bool found = std::find(existing_names.begin(), | 1222 bool found = std::find(existing_names.begin(), |
1231 existing_names.end(), | 1223 existing_names.end(), |
1232 new_name) != existing_names.end(); | 1224 new_name) != existing_names.end(); |
1233 if (!found) { | 1225 if (!found) { |
1234 existing_name->second.push_back(','); | 1226 existing_name->second.push_back(','); |
1235 existing_name->second.append(new_name); | 1227 existing_name->second.append(new_name); |
1236 } | 1228 } |
1237 } | 1229 } |
1238 } | 1230 } |
| 1231 } |
1239 | 1232 |
1240 TraceEvent trace_event(thread_id, | 1233 TraceEvent trace_event(thread_id, |
1241 now, phase, category_group_enabled, name, id, | 1234 now, phase, category_group_enabled, name, id, |
1242 num_args, arg_names, arg_types, arg_values, | 1235 num_args, arg_names, arg_types, arg_values, |
1243 convertable_values, flags); | 1236 convertable_values, flags); |
| 1237 |
| 1238 do { |
| 1239 AutoLock lock(lock_); |
| 1240 |
| 1241 event_callback_copy = event_callback_; |
| 1242 if (logged_events_->IsFull()) |
| 1243 break; |
1244 | 1244 |
1245 logged_events_->AddEvent(trace_event); | 1245 logged_events_->AddEvent(trace_event); |
1246 | 1246 |
1247 if (trace_options_ & ECHO_TO_CONSOLE) { | 1247 if (trace_options_ & ECHO_TO_CONSOLE) { |
| 1248 TimeDelta duration; |
| 1249 if (phase == TRACE_EVENT_PHASE_END) { |
| 1250 duration = timestamp - thread_event_start_times_[thread_id].top(); |
| 1251 thread_event_start_times_[thread_id].pop(); |
| 1252 } |
| 1253 |
1248 std::string thread_name = thread_names_[thread_id]; | 1254 std::string thread_name = thread_names_[thread_id]; |
1249 if (thread_colors_.find(thread_name) == thread_colors_.end()) | 1255 if (thread_colors_.find(thread_name) == thread_colors_.end()) |
1250 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; | 1256 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; |
1251 | 1257 |
1252 std::ostringstream log; | 1258 std::ostringstream log; |
1253 log << base::StringPrintf("%s: \x1b[0;3%dm", | 1259 log << base::StringPrintf("%s: \x1b[0;3%dm", |
1254 thread_name.c_str(), | 1260 thread_name.c_str(), |
1255 thread_colors_[thread_name]); | 1261 thread_colors_[thread_name]); |
1256 | 1262 |
1257 size_t depth = 0; | 1263 size_t depth = 0; |
1258 if (thread_event_start_times_.find(thread_id) != | 1264 if (thread_event_start_times_.find(thread_id) != |
1259 thread_event_start_times_.end()) | 1265 thread_event_start_times_.end()) |
1260 depth = thread_event_start_times_[thread_id].size(); | 1266 depth = thread_event_start_times_[thread_id].size(); |
1261 | 1267 |
1262 for (size_t i = 0; i < depth; ++i) | 1268 for (size_t i = 0; i < depth; ++i) |
1263 log << "| "; | 1269 log << "| "; |
1264 | 1270 |
1265 trace_event.AppendPrettyPrinted(&log); | 1271 trace_event.AppendPrettyPrinted(&log); |
1266 if (phase == TRACE_EVENT_PHASE_END) | 1272 if (phase == TRACE_EVENT_PHASE_END) |
1267 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); | 1273 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); |
1268 | 1274 |
1269 LOG(ERROR) << log.str() << "\x1b[0;m"; | 1275 LOG(ERROR) << log.str() << "\x1b[0;m"; |
| 1276 |
| 1277 if (phase == TRACE_EVENT_PHASE_BEGIN) |
| 1278 thread_event_start_times_[thread_id].push(timestamp); |
1270 } | 1279 } |
1271 | 1280 |
1272 if (logged_events_->IsFull()) | 1281 if (logged_events_->IsFull()) |
1273 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); | 1282 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); |
1274 | 1283 |
1275 if (watch_category_ == category_group_enabled && watch_event_name_ == name) | 1284 if (watch_category_ == category_group_enabled && watch_event_name_ == name) |
1276 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); | 1285 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); |
1277 } while (0); // release lock | 1286 } while (0); // release lock |
1278 | 1287 |
1279 if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_CONSOLE) | |
1280 thread_event_start_times_[thread_id].push(timestamp); | |
1281 | |
1282 notifier.SendNotificationIfAny(); | 1288 notifier.SendNotificationIfAny(); |
1283 if (event_callback_copy != NULL) { | 1289 if (event_callback_copy != NULL) { |
1284 event_callback_copy(phase, category_group_enabled, name, id, | 1290 event_callback_copy(phase, category_group_enabled, name, id, |
1285 num_args, arg_names, arg_types, arg_values, | 1291 num_args, arg_names, arg_types, arg_values, |
1286 flags); | 1292 flags); |
1287 } | 1293 } |
1288 } | 1294 } |
1289 | 1295 |
1290 void TraceLog::AddTraceEventEtw(char phase, | 1296 void TraceLog::AddTraceEventEtw(char phase, |
1291 const char* name, | 1297 const char* name, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 void TraceLog::UpdateProcessLabel( | 1458 void TraceLog::UpdateProcessLabel( |
1453 int label_id, const std::string& current_label) { | 1459 int label_id, const std::string& current_label) { |
1454 if(!current_label.length()) | 1460 if(!current_label.length()) |
1455 return RemoveProcessLabel(label_id); | 1461 return RemoveProcessLabel(label_id); |
1456 | 1462 |
1457 AutoLock lock(lock_); | 1463 AutoLock lock(lock_); |
1458 process_labels_[label_id] = current_label; | 1464 process_labels_[label_id] = current_label; |
1459 } | 1465 } |
1460 | 1466 |
1461 void TraceLog::RemoveProcessLabel(int label_id) { | 1467 void TraceLog::RemoveProcessLabel(int label_id) { |
| 1468 AutoLock lock(lock_); |
1462 base::hash_map<int, std::string>::iterator it = process_labels_.find( | 1469 base::hash_map<int, std::string>::iterator it = process_labels_.find( |
1463 label_id); | 1470 label_id); |
1464 if (it == process_labels_.end()) | 1471 if (it == process_labels_.end()) |
1465 return; | 1472 return; |
1466 | 1473 |
1467 process_labels_.erase(it); | 1474 process_labels_.erase(it); |
1468 } | 1475 } |
1469 | 1476 |
1470 void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) { | 1477 void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) { |
1471 AutoLock lock(lock_); | 1478 AutoLock lock(lock_); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 0, // num_args | 1687 0, // num_args |
1681 NULL, // arg_names | 1688 NULL, // arg_names |
1682 NULL, // arg_types | 1689 NULL, // arg_types |
1683 NULL, // arg_values | 1690 NULL, // arg_values |
1684 NULL, // convertable values | 1691 NULL, // convertable values |
1685 TRACE_EVENT_FLAG_NONE); // flags | 1692 TRACE_EVENT_FLAG_NONE); // flags |
1686 } | 1693 } |
1687 } | 1694 } |
1688 | 1695 |
1689 } // namespace trace_event_internal | 1696 } // namespace trace_event_internal |
OLD | NEW |