| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "base/debug/trace_event.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // Controls the number of trace events we will buffer in-memory | 39 // Controls the number of trace events we will buffer in-memory |
| 40 // before throwing them away. | 40 // before throwing them away. |
| 41 const size_t kTraceEventBufferSize = 500000; | 41 const size_t kTraceEventBufferSize = 500000; |
| 42 const size_t kTraceEventBatchSize = 1000; | 42 const size_t kTraceEventBatchSize = 1000; |
| 43 | 43 |
| 44 #define TRACE_EVENT_MAX_CATEGORIES 100 | 44 #define TRACE_EVENT_MAX_CATEGORIES 100 |
| 45 | 45 |
| 46 namespace { | 46 namespace { |
| 47 | 47 |
| 48 // Specify these values when the corresponding argument of AddTraceEvent is not | 48 // Parallel arrays g_categories and g_category_enabled are separate so that |
| 49 // used. | 49 // a pointer to a member of g_category_enabled can be easily converted to an |
| 50 static const char* kNoArgName = NULL; | 50 // index into g_categories. This allows macros to deal only with char enabled |
| 51 static const int kNoArgValue = 0; | 51 // pointers from g_category_enabled, and we can convert internally to determine |
| 52 static const int kNoThreshholdBeginId = -1; | 52 // the category name from the char enabled pointer. |
| 53 static const int64 kNoThresholdValue = 0; | 53 const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = { |
| 54 static const int kNoEventId = 0; | 54 "tracing already shutdown", |
| 55 | 55 "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", |
| 56 TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = { | 56 "__metadata", |
| 57 { "tracing already shutdown", false }, | |
| 58 { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", | |
| 59 false }, | |
| 60 { "__metadata", | |
| 61 false } | |
| 62 }; | 57 }; |
| 63 const TraceCategory* const g_category_already_shutdown = | 58 // The enabled flag is char instead of bool so that the API can be used from C. |
| 64 &g_categories[0]; | 59 unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 }; |
| 65 const TraceCategory* const g_category_categories_exhausted = | 60 const int g_category_already_shutdown = 0; |
| 66 &g_categories[1]; | 61 const int g_category_categories_exhausted = 1; |
| 67 const TraceCategory* const g_category_metadata = | 62 const int g_category_metadata = 2; |
| 68 &g_categories[2]; | |
| 69 int g_category_index = 3; // skip initial 3 categories | 63 int g_category_index = 3; // skip initial 3 categories |
| 70 | 64 |
| 71 // The most-recently captured name of the current thread | 65 // The most-recently captured name of the current thread |
| 72 LazyInstance<ThreadLocalPointer<const char>, | 66 LazyInstance<ThreadLocalPointer<const char>, |
| 73 LeakyLazyInstanceTraits<ThreadLocalPointer<const char> > > | 67 LeakyLazyInstanceTraits<ThreadLocalPointer<const char> > > |
| 74 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; | 68 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; |
| 75 | 69 |
| 76 } // namespace | 70 void AppendValueAsJSON(unsigned char type, |
| 77 | 71 TraceEvent::TraceValue value, |
| 78 //////////////////////////////////////////////////////////////////////////////// | 72 std::string* out) { |
| 79 // | |
| 80 // TraceValue | |
| 81 // | |
| 82 //////////////////////////////////////////////////////////////////////////////// | |
| 83 | |
| 84 void TraceValue::AppendAsJSON(std::string* out) const { | |
| 85 std::string::size_type start_pos; | 73 std::string::size_type start_pos; |
| 86 switch (type_) { | 74 switch (type) { |
| 87 case TRACE_TYPE_BOOL: | 75 case TRACE_VALUE_TYPE_BOOL: |
| 88 *out += as_bool() ? "true" : "false"; | 76 *out += value.as_bool ? "true" : "false"; |
| 89 break; | 77 break; |
| 90 case TRACE_TYPE_UINT: | 78 case TRACE_VALUE_TYPE_UINT: |
| 91 StringAppendF(out, "%" PRIu64, as_uint()); | 79 StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint)); |
| 92 break; | 80 break; |
| 93 case TRACE_TYPE_INT: | 81 case TRACE_VALUE_TYPE_INT: |
| 94 StringAppendF(out, "%" PRId64, as_int()); | 82 StringAppendF(out, "%" PRId64, static_cast<int64>(value.as_int)); |
| 95 break; | 83 break; |
| 96 case TRACE_TYPE_DOUBLE: | 84 case TRACE_VALUE_TYPE_DOUBLE: |
| 97 StringAppendF(out, "%f", as_double()); | 85 StringAppendF(out, "%f", value.as_double); |
| 98 break; | 86 break; |
| 99 case TRACE_TYPE_POINTER: | 87 case TRACE_VALUE_TYPE_POINTER: |
| 100 // JSON only supports double and int numbers. | 88 // JSON only supports double and int numbers. |
| 101 // So as not to lose bits from a 64-bit pointer, output as a hex string. | 89 // So as not to lose bits from a 64-bit pointer, output as a hex string. |
| 102 StringAppendF(out, "\"%" PRIx64 "\"", static_cast<uint64>( | 90 StringAppendF(out, "\"%" PRIx64 "\"", static_cast<uint64>( |
| 103 reinterpret_cast<intptr_t>( | 91 reinterpret_cast<intptr_t>( |
| 104 as_pointer()))); | 92 value.as_pointer))); |
| 105 break; | 93 break; |
| 106 case TRACE_TYPE_STRING: | 94 case TRACE_VALUE_TYPE_STRING: |
| 107 case TRACE_TYPE_STATIC_STRING: | 95 case TRACE_VALUE_TYPE_COPY_STRING: |
| 108 *out += "\""; | 96 *out += "\""; |
| 109 start_pos = out->size(); | 97 start_pos = out->size(); |
| 110 *out += as_string() ? as_string() : "NULL"; | 98 *out += value.as_string ? value.as_string : "NULL"; |
| 111 // insert backslash before special characters for proper json format. | 99 // insert backslash before special characters for proper json format. |
| 112 while ((start_pos = out->find_first_of("\\\"", start_pos)) != | 100 while ((start_pos = out->find_first_of("\\\"", start_pos)) != |
| 113 std::string::npos) { | 101 std::string::npos) { |
| 114 out->insert(start_pos, 1, '\\'); | 102 out->insert(start_pos, 1, '\\'); |
| 115 // skip inserted escape character and following character. | 103 // skip inserted escape character and following character. |
| 116 start_pos += 2; | 104 start_pos += 2; |
| 117 } | 105 } |
| 118 *out += "\""; | 106 *out += "\""; |
| 119 break; | 107 break; |
| 120 default: | 108 default: |
| 121 NOTREACHED() << "Don't know how to print this value"; | 109 NOTREACHED() << "Don't know how to print this value"; |
| 122 break; | 110 break; |
| 123 } | 111 } |
| 124 } | 112 } |
| 125 | 113 |
| 126 //////////////////////////////////////////////////////////////////////////////// | 114 } // namespace |
| 127 // | |
| 128 // TraceID | |
| 129 // | |
| 130 //////////////////////////////////////////////////////////////////////////////// | |
| 131 | |
| 132 TraceID::TraceID(void* rhs) { | |
| 133 data_ = base::debug::TraceLog::GetInstance()->GetIntraProcessID( | |
| 134 static_cast<uint64>(reinterpret_cast<uintptr_t>(rhs))); | |
| 135 } | |
| 136 | 115 |
| 137 //////////////////////////////////////////////////////////////////////////////// | 116 //////////////////////////////////////////////////////////////////////////////// |
| 138 // | 117 // |
| 139 // TraceEvent | 118 // TraceEvent |
| 140 // | 119 // |
| 141 //////////////////////////////////////////////////////////////////////////////// | 120 //////////////////////////////////////////////////////////////////////////////// |
| 142 | 121 |
| 143 namespace { | 122 namespace { |
| 144 | 123 |
| 145 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } | 124 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } |
| 146 | 125 |
| 147 // Copies |*member| into |*buffer|, sets |*member| to point to this new | 126 // Copies |*member| into |*buffer|, sets |*member| to point to this new |
| 148 // location, and then advances |*buffer| by the amount written. | 127 // location, and then advances |*buffer| by the amount written. |
| 149 void CopyTraceEventParameter(char** buffer, | 128 void CopyTraceEventParameter(char** buffer, |
| 150 const char** member, | 129 const char** member, |
| 151 const char* end) { | 130 const char* end) { |
| 152 if (*member) { | 131 if (*member) { |
| 153 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; | 132 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; |
| 154 DCHECK_LE(static_cast<int>(written), end - *buffer); | 133 DCHECK_LE(static_cast<int>(written), end - *buffer); |
| 155 *member = *buffer; | 134 *member = *buffer; |
| 156 *buffer += written; | 135 *buffer += written; |
| 157 } | 136 } |
| 158 } | 137 } |
| 159 | 138 |
| 160 } // namespace | 139 } // namespace |
| 161 | 140 |
| 162 TraceEvent::TraceEvent() | 141 TraceEvent::TraceEvent() |
| 163 : id_(0u), | 142 : id_(0u), |
| 164 category_(NULL), | 143 category_enabled_(NULL), |
| 165 name_(NULL), | 144 name_(NULL), |
| 166 thread_id_(0), | 145 thread_id_(0), |
| 167 phase_(TRACE_EVENT_PHASE_BEGIN), | 146 phase_(TRACE_EVENT_PHASE_BEGIN), |
| 168 flags_(0) { | 147 flags_(0) { |
| 169 arg_names_[0] = NULL; | 148 arg_names_[0] = NULL; |
| 170 arg_names_[1] = NULL; | 149 arg_names_[1] = NULL; |
| 171 } | 150 } |
| 172 | 151 |
| 173 TraceEvent::TraceEvent(int thread_id, | 152 TraceEvent::TraceEvent(int thread_id, |
| 174 TimeTicks timestamp, | 153 TimeTicks timestamp, |
| 175 TraceEventPhase phase, | 154 char phase, |
| 176 const TraceCategory* category, | 155 const unsigned char* category_enabled, |
| 177 const char* name, | 156 const char* name, |
| 178 TraceID id, | 157 unsigned long long id, |
| 179 const char* arg1_name, const TraceValue& arg1_val, | 158 int num_args, |
| 180 const char* arg2_name, const TraceValue& arg2_val, | 159 const char** arg_names, |
| 181 TraceEventFlags flags) | 160 const unsigned char* arg_types, |
| 161 const unsigned long long* arg_values, |
| 162 unsigned char flags) |
| 182 : timestamp_(timestamp), | 163 : timestamp_(timestamp), |
| 183 id_(id), | 164 id_(id), |
| 184 category_(category), | 165 category_enabled_(category_enabled), |
| 185 name_(name), | 166 name_(name), |
| 186 thread_id_(thread_id), | 167 thread_id_(thread_id), |
| 187 phase_(phase), | 168 phase_(phase), |
| 188 flags_(flags) { | 169 flags_(flags) { |
| 189 COMPILE_ASSERT(kTraceMaxNumArgs == 2, TraceEvent_arg_count_out_of_sync); | 170 // Clamp num_args since it may have been set by a third_party library. |
| 190 arg_names_[0] = arg1_name; | 171 num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; |
| 191 arg_names_[1] = arg2_name; | 172 int i = 0; |
| 192 arg_values_[0] = arg1_val; | 173 for (; i < num_args; ++i) { |
| 193 arg_values_[1] = arg2_val; | 174 arg_names_[i] = arg_names[i]; |
| 175 arg_values_[i].as_uint = arg_values[i]; |
| 176 arg_types_[i] = arg_types[i]; |
| 177 } |
| 178 for (; i < kTraceMaxNumArgs; ++i) { |
| 179 arg_names_[i] = NULL; |
| 180 arg_values_[i].as_uint = 0u; |
| 181 arg_types_[i] = TRACE_VALUE_TYPE_UINT; |
| 182 } |
| 194 | 183 |
| 195 bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); | 184 bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); |
| 196 size_t alloc_size = 0; | 185 size_t alloc_size = 0; |
| 197 if (copy) { | 186 if (copy) { |
| 198 alloc_size += GetAllocLength(name); | 187 alloc_size += GetAllocLength(name); |
| 199 alloc_size += GetAllocLength(arg1_name); | 188 for (i = 0; i < num_args; ++i) { |
| 200 alloc_size += GetAllocLength(arg2_name); | 189 alloc_size += GetAllocLength(arg_names_[i]); |
| 190 if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) |
| 191 arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; |
| 192 } |
| 201 } | 193 } |
| 202 | 194 |
| 203 bool arg1_is_copy = (arg1_val.type() == TraceValue::TRACE_TYPE_STRING); | 195 bool arg_is_copy[kTraceMaxNumArgs]; |
| 204 bool arg2_is_copy = (arg2_val.type() == TraceValue::TRACE_TYPE_STRING); | 196 for (i = 0; i < num_args; ++i) { |
| 205 | 197 // We only take a copy of arg_vals if they are of type COPY_STRING. |
| 206 // We only take a copy of arg_vals if they are of type string (not static | 198 arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); |
| 207 // string), regardless of the |copy| flag. | 199 if (arg_is_copy[i]) |
| 208 if (arg1_is_copy) | 200 alloc_size += GetAllocLength(arg_values_[i].as_string); |
| 209 alloc_size += GetAllocLength(arg1_val.as_string()); | 201 } |
| 210 if (arg2_is_copy) | |
| 211 alloc_size += GetAllocLength(arg2_val.as_string()); | |
| 212 | 202 |
| 213 if (alloc_size) { | 203 if (alloc_size) { |
| 214 parameter_copy_storage_ = new base::RefCountedString; | 204 parameter_copy_storage_ = new base::RefCountedString; |
| 215 parameter_copy_storage_->data().resize(alloc_size); | 205 parameter_copy_storage_->data().resize(alloc_size); |
| 216 char* ptr = string_as_array(¶meter_copy_storage_->data()); | 206 char* ptr = string_as_array(¶meter_copy_storage_->data()); |
| 217 const char* end = ptr + alloc_size; | 207 const char* end = ptr + alloc_size; |
| 218 if (copy) { | 208 if (copy) { |
| 219 CopyTraceEventParameter(&ptr, &name_, end); | 209 CopyTraceEventParameter(&ptr, &name_, end); |
| 220 CopyTraceEventParameter(&ptr, &arg_names_[0], end); | 210 for (i = 0; i < num_args; ++i) |
| 221 CopyTraceEventParameter(&ptr, &arg_names_[1], end); | 211 CopyTraceEventParameter(&ptr, &arg_names_[i], end); |
| 222 } | 212 } |
| 223 if (arg1_is_copy) | 213 for (i = 0; i < num_args; ++i) { |
| 224 CopyTraceEventParameter(&ptr, arg_values_[0].as_assignable_string(), end); | 214 if (arg_is_copy[i]) |
| 225 if (arg2_is_copy) | 215 CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end); |
| 226 CopyTraceEventParameter(&ptr, arg_values_[1].as_assignable_string(), end); | 216 } |
| 227 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; | 217 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; |
| 228 } | 218 } |
| 229 } | 219 } |
| 230 | 220 |
| 231 TraceEvent::~TraceEvent() { | 221 TraceEvent::~TraceEvent() { |
| 232 } | 222 } |
| 233 | 223 |
| 234 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events, | 224 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
| 235 size_t start, | 225 size_t start, |
| 236 size_t count, | 226 size_t count, |
| 237 std::string* out) { | 227 std::string* out) { |
| 238 for (size_t i = 0; i < count && start + i < events.size(); ++i) { | 228 for (size_t i = 0; i < count && start + i < events.size(); ++i) { |
| 239 if (i > 0) | 229 if (i > 0) |
| 240 *out += ","; | 230 *out += ","; |
| 241 events[i + start].AppendAsJSON(out); | 231 events[i + start].AppendAsJSON(out); |
| 242 } | 232 } |
| 243 } | 233 } |
| 244 | 234 |
| 245 void TraceEvent::AppendAsJSON(std::string* out) const { | 235 void TraceEvent::AppendAsJSON(std::string* out) const { |
| 246 const char phase_char = GetPhaseChar(phase_); | |
| 247 int64 time_int64 = timestamp_.ToInternalValue(); | 236 int64 time_int64 = timestamp_.ToInternalValue(); |
| 248 int process_id = TraceLog::GetInstance()->process_id(); | 237 int process_id = TraceLog::GetInstance()->process_id(); |
| 249 // Category name checked at category creation time. | 238 // Category name checked at category creation time. |
| 250 DCHECK(!strchr(name_, '"')); | 239 DCHECK(!strchr(name_, '"')); |
| 251 StringAppendF(out, | 240 StringAppendF(out, |
| 252 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," | 241 "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," |
| 253 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", | 242 "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", |
| 254 category_->name, | 243 TraceLog::GetCategoryName(category_enabled_), |
| 255 process_id, | 244 process_id, |
| 256 thread_id_, | 245 thread_id_, |
| 257 time_int64, | 246 time_int64, |
| 258 phase_char, | 247 phase_, |
| 259 name_); | 248 name_); |
| 260 | 249 |
| 261 // Output argument names and values, stop at first NULL argument name. | 250 // Output argument names and values, stop at first NULL argument name. |
| 262 for (size_t i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { | 251 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { |
| 263 if (i > 0) | 252 if (i > 0) |
| 264 *out += ","; | 253 *out += ","; |
| 265 *out += "\""; | 254 *out += "\""; |
| 266 *out += arg_names_[i]; | 255 *out += arg_names_[i]; |
| 267 *out += "\":"; | 256 *out += "\":"; |
| 268 arg_values_[i].AppendAsJSON(out); | 257 AppendValueAsJSON(arg_types_[i], arg_values_[i], out); |
| 269 } | 258 } |
| 270 *out += "}"; | 259 *out += "}"; |
| 271 | 260 |
| 272 // If id_ is set, print it out as a hex string so we don't loose any | 261 // If id_ is set, print it out as a hex string so we don't loose any |
| 273 // bits (it might be a 64-bit pointer). | 262 // bits (it might be a 64-bit pointer). |
| 274 if (flags_ & TRACE_EVENT_FLAG_HAS_ID) | 263 if (flags_ & TRACE_EVENT_FLAG_HAS_ID) |
| 275 StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", id_.data()); | 264 StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", static_cast<uint64>(id_)); |
| 276 *out += "}"; | 265 *out += "}"; |
| 277 } | 266 } |
| 278 | 267 |
| 279 //////////////////////////////////////////////////////////////////////////////// | 268 //////////////////////////////////////////////////////////////////////////////// |
| 280 // | 269 // |
| 281 // TraceResultBuffer | 270 // TraceResultBuffer |
| 282 // | 271 // |
| 283 //////////////////////////////////////////////////////////////////////////////// | 272 //////////////////////////////////////////////////////////////////////////////// |
| 284 | 273 |
| 285 TraceResultBuffer::OutputCallback | 274 TraceResultBuffer::OutputCallback |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 320 } |
| 332 | 321 |
| 333 TraceLog::TraceLog() | 322 TraceLog::TraceLog() |
| 334 : enabled_(false) { | 323 : enabled_(false) { |
| 335 SetProcessID(static_cast<int>(base::GetCurrentProcId())); | 324 SetProcessID(static_cast<int>(base::GetCurrentProcId())); |
| 336 } | 325 } |
| 337 | 326 |
| 338 TraceLog::~TraceLog() { | 327 TraceLog::~TraceLog() { |
| 339 } | 328 } |
| 340 | 329 |
| 341 const TraceCategory* TraceLog::GetCategory(const char* name) { | 330 const unsigned char* TraceLog::GetCategoryEnabled(const char* name) { |
| 342 TraceLog* tracelog = GetInstance(); | 331 TraceLog* tracelog = GetInstance(); |
| 343 if (!tracelog){ | 332 if (!tracelog) { |
| 344 DCHECK(!g_category_already_shutdown->enabled); | 333 DCHECK(!g_category_enabled[g_category_already_shutdown]); |
| 345 return g_category_already_shutdown; | 334 return &g_category_enabled[g_category_already_shutdown]; |
| 346 } | 335 } |
| 347 return tracelog->GetCategoryInternal(name); | 336 return tracelog->GetCategoryEnabledInternal(name); |
| 337 } |
| 338 |
| 339 const char* TraceLog::GetCategoryName(const unsigned char* category_enabled) { |
| 340 // Calculate the index of the category by finding category_enabled in |
| 341 // g_category_enabled array. |
| 342 uintptr_t category_begin = reinterpret_cast<uintptr_t>(g_category_enabled); |
| 343 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); |
| 344 DCHECK(category_ptr >= category_begin && |
| 345 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + |
| 346 TRACE_EVENT_MAX_CATEGORIES)) << |
| 347 "out of bounds category pointer"; |
| 348 uintptr_t category_index = |
| 349 (category_ptr - category_begin) / sizeof(g_category_enabled[0]); |
| 350 return g_categories[category_index]; |
| 348 } | 351 } |
| 349 | 352 |
| 350 static void EnableMatchingCategory(int category_index, | 353 static void EnableMatchingCategory(int category_index, |
| 351 const std::vector<std::string>& patterns, | 354 const std::vector<std::string>& patterns, |
| 352 bool is_included) { | 355 unsigned char is_included) { |
| 353 std::vector<std::string>::const_iterator ci = patterns.begin(); | 356 std::vector<std::string>::const_iterator ci = patterns.begin(); |
| 354 bool is_match = false; | 357 bool is_match = false; |
| 355 for (; ci != patterns.end(); ++ci) { | 358 for (; ci != patterns.end(); ++ci) { |
| 356 is_match = MatchPattern(g_categories[category_index].name, ci->c_str()); | 359 is_match = MatchPattern(g_categories[category_index], ci->c_str()); |
| 357 if (is_match) | 360 if (is_match) |
| 358 break; | 361 break; |
| 359 } | 362 } |
| 360 ANNOTATE_BENIGN_RACE(&g_categories[category_index].enabled, | 363 ANNOTATE_BENIGN_RACE(&g_category_enabled[category_index], |
| 361 "trace_event category enabled"); | 364 "trace_event category enabled"); |
| 362 g_categories[category_index].enabled = is_match ? is_included : !is_included; | 365 g_category_enabled[category_index] = is_match ? |
| 366 is_included : (is_included ^ 1); |
| 363 } | 367 } |
| 364 | 368 |
| 365 // Enable/disable each category based on the category filters in |patterns|. | 369 // Enable/disable each category based on the category filters in |patterns|. |
| 366 // If the category name matches one of the patterns, its enabled status is set | 370 // If the category name matches one of the patterns, its enabled status is set |
| 367 // to |is_included|. Otherwise its enabled status is set to !|is_included|. | 371 // to |is_included|. Otherwise its enabled status is set to !|is_included|. |
| 368 static void EnableMatchingCategories(const std::vector<std::string>& patterns, | 372 static void EnableMatchingCategories(const std::vector<std::string>& patterns, |
| 369 bool is_included) { | 373 unsigned char is_included) { |
| 370 for (int i = 0; i < g_category_index; i++) | 374 for (int i = 0; i < g_category_index; i++) |
| 371 EnableMatchingCategory(i, patterns, is_included); | 375 EnableMatchingCategory(i, patterns, is_included); |
| 372 } | 376 } |
| 373 | 377 |
| 374 const TraceCategory* TraceLog::GetCategoryInternal(const char* name) { | 378 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { |
| 375 AutoLock lock(lock_); | 379 AutoLock lock(lock_); |
| 376 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; | 380 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; |
| 377 | 381 |
| 378 // Search for pre-existing category matching this name | 382 // Search for pre-existing category matching this name |
| 379 for (int i = 0; i < g_category_index; i++) { | 383 for (int i = 0; i < g_category_index; i++) { |
| 380 if (strcmp(g_categories[i].name, name) == 0) | 384 if (strcmp(g_categories[i], name) == 0) |
| 381 return &g_categories[i]; | 385 return &g_category_enabled[i]; |
| 382 } | 386 } |
| 383 | 387 |
| 384 // Create a new category | 388 // Create a new category |
| 385 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << | 389 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << |
| 386 "must increase TRACE_EVENT_MAX_CATEGORIES"; | 390 "must increase TRACE_EVENT_MAX_CATEGORIES"; |
| 387 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { | 391 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { |
| 388 int new_index = g_category_index++; | 392 int new_index = g_category_index++; |
| 389 g_categories[new_index].name = name; | 393 g_categories[new_index] = name; |
| 390 DCHECK(!g_categories[new_index].enabled); | 394 DCHECK(!g_category_enabled[new_index]); |
| 391 if (enabled_) { | 395 if (enabled_) { |
| 392 // Note that if both included and excluded_categories are empty, the else | 396 // Note that if both included and excluded_categories are empty, the else |
| 393 // clause below excludes nothing, thereby enabling this category. | 397 // clause below excludes nothing, thereby enabling this category. |
| 394 if (!included_categories_.empty()) | 398 if (!included_categories_.empty()) |
| 395 EnableMatchingCategory(new_index, included_categories_, true); | 399 EnableMatchingCategory(new_index, included_categories_, 1); |
| 396 else | 400 else |
| 397 EnableMatchingCategory(new_index, excluded_categories_, false); | 401 EnableMatchingCategory(new_index, excluded_categories_, 0); |
| 398 } else { | 402 } else { |
| 399 ANNOTATE_BENIGN_RACE(&g_categories[new_index].enabled, | 403 ANNOTATE_BENIGN_RACE(&g_category_enabled[new_index], |
| 400 "trace_event category enabled"); | 404 "trace_event category enabled"); |
| 401 g_categories[new_index].enabled = false; | 405 g_category_enabled[new_index] = 0; |
| 402 } | 406 } |
| 403 return &g_categories[new_index]; | 407 return &g_category_enabled[new_index]; |
| 404 } else { | 408 } else { |
| 405 return g_category_categories_exhausted; | 409 return &g_category_enabled[g_category_categories_exhausted]; |
| 406 } | 410 } |
| 407 } | 411 } |
| 408 | 412 |
| 409 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { | 413 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { |
| 410 AutoLock lock(lock_); | 414 AutoLock lock(lock_); |
| 411 for (int i = 0; i < g_category_index; i++) | 415 for (int i = 0; i < g_category_index; i++) |
| 412 categories->push_back(g_categories[i].name); | 416 categories->push_back(g_categories[i]); |
| 413 } | 417 } |
| 414 | 418 |
| 415 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, | 419 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, |
| 416 const std::vector<std::string>& excluded_categories) { | 420 const std::vector<std::string>& excluded_categories) { |
| 417 AutoLock lock(lock_); | 421 AutoLock lock(lock_); |
| 418 if (enabled_) | 422 if (enabled_) |
| 419 return; | 423 return; |
| 420 logged_events_.reserve(1024); | 424 logged_events_.reserve(1024); |
| 421 enabled_ = true; | 425 enabled_ = true; |
| 422 included_categories_ = included_categories; | 426 included_categories_ = included_categories; |
| 423 excluded_categories_ = excluded_categories; | 427 excluded_categories_ = excluded_categories; |
| 424 // Note that if both included and excluded_categories are empty, the else | 428 // Note that if both included and excluded_categories are empty, the else |
| 425 // clause below excludes nothing, thereby enabling all categories. | 429 // clause below excludes nothing, thereby enabling all categories. |
| 426 if (!included_categories_.empty()) | 430 if (!included_categories_.empty()) |
| 427 EnableMatchingCategories(included_categories_, true); | 431 EnableMatchingCategories(included_categories_, 1); |
| 428 else | 432 else |
| 429 EnableMatchingCategories(excluded_categories_, false); | 433 EnableMatchingCategories(excluded_categories_, 0); |
| 430 } | 434 } |
| 431 | 435 |
| 432 void TraceLog::SetEnabled(const std::string& categories) { | 436 void TraceLog::SetEnabled(const std::string& categories) { |
| 433 std::vector<std::string> included, excluded; | 437 std::vector<std::string> included, excluded; |
| 434 // Tokenize list of categories, delimited by ','. | 438 // Tokenize list of categories, delimited by ','. |
| 435 StringTokenizer tokens(categories, ","); | 439 StringTokenizer tokens(categories, ","); |
| 436 while (tokens.GetNext()) { | 440 while (tokens.GetNext()) { |
| 437 bool is_included = true; | 441 bool is_included = true; |
| 438 std::string category = tokens.token(); | 442 std::string category = tokens.token(); |
| 439 // Excluded categories start with '-'. | 443 // Excluded categories start with '-'. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 463 void TraceLog::SetDisabled() { | 467 void TraceLog::SetDisabled() { |
| 464 { | 468 { |
| 465 AutoLock lock(lock_); | 469 AutoLock lock(lock_); |
| 466 if (!enabled_) | 470 if (!enabled_) |
| 467 return; | 471 return; |
| 468 | 472 |
| 469 enabled_ = false; | 473 enabled_ = false; |
| 470 included_categories_.clear(); | 474 included_categories_.clear(); |
| 471 excluded_categories_.clear(); | 475 excluded_categories_.clear(); |
| 472 for (int i = 0; i < g_category_index; i++) | 476 for (int i = 0; i < g_category_index; i++) |
| 473 g_categories[i].enabled = false; | 477 g_category_enabled[i] = 0; |
| 474 AddThreadNameMetadataEvents(); | 478 AddThreadNameMetadataEvents(); |
| 475 AddClockSyncMetadataEvents(); | 479 AddClockSyncMetadataEvents(); |
| 476 } // release lock | 480 } // release lock |
| 477 Flush(); | 481 Flush(); |
| 478 } | 482 } |
| 479 | 483 |
| 480 void TraceLog::SetEnabled(bool enabled) { | 484 void TraceLog::SetEnabled(bool enabled) { |
| 481 if (enabled) | 485 if (enabled) |
| 482 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); | 486 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); |
| 483 else | 487 else |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 scoped_refptr<RefCountedString> json_events_str_ptr = | 520 scoped_refptr<RefCountedString> json_events_str_ptr = |
| 517 new RefCountedString(); | 521 new RefCountedString(); |
| 518 TraceEvent::AppendEventsAsJSON(previous_logged_events, | 522 TraceEvent::AppendEventsAsJSON(previous_logged_events, |
| 519 i, | 523 i, |
| 520 kTraceEventBatchSize, | 524 kTraceEventBatchSize, |
| 521 &(json_events_str_ptr->data)); | 525 &(json_events_str_ptr->data)); |
| 522 output_callback_copy.Run(json_events_str_ptr); | 526 output_callback_copy.Run(json_events_str_ptr); |
| 523 } | 527 } |
| 524 } | 528 } |
| 525 | 529 |
| 526 int TraceLog::AddTraceEvent(TraceEventPhase phase, | 530 int TraceLog::AddTraceEvent(char phase, |
| 527 const TraceCategory* category, | 531 const unsigned char* category_enabled, |
| 528 const char* name, | 532 const char* name, |
| 529 TraceID id, | 533 unsigned long long id, |
| 530 const char* arg1_name, TraceValue arg1_val, | 534 int num_args, |
| 531 const char* arg2_name, TraceValue arg2_val, | 535 const char** arg_names, |
| 536 const unsigned char* arg_types, |
| 537 const unsigned long long* arg_values, |
| 532 int threshold_begin_id, | 538 int threshold_begin_id, |
| 533 int64 threshold, | 539 long long threshold, |
| 534 TraceEventFlags flags) { | 540 unsigned char flags) { |
| 535 DCHECK(name); | 541 DCHECK(name); |
| 536 TimeTicks now = TimeTicks::HighResNow(); | 542 TimeTicks now = TimeTicks::HighResNow(); |
| 537 BufferFullCallback buffer_full_callback_copy; | 543 BufferFullCallback buffer_full_callback_copy; |
| 538 int ret_begin_id = -1; | 544 int ret_begin_id = -1; |
| 539 { | 545 { |
| 540 AutoLock lock(lock_); | 546 AutoLock lock(lock_); |
| 541 if (!category->enabled) | 547 if (!*category_enabled) |
| 542 return -1; | 548 return -1; |
| 543 if (logged_events_.size() >= kTraceEventBufferSize) | 549 if (logged_events_.size() >= kTraceEventBufferSize) |
| 544 return -1; | 550 return -1; |
| 545 | 551 |
| 546 int thread_id = static_cast<int>(PlatformThread::CurrentId()); | 552 int thread_id = static_cast<int>(PlatformThread::CurrentId()); |
| 547 | 553 |
| 548 const char* new_name = PlatformThread::GetName(); | 554 const char* new_name = PlatformThread::GetName(); |
| 549 // Check if the thread name has been set or changed since the previous | 555 // Check if the thread name has been set or changed since the previous |
| 550 // call (if any), but don't bother if the new name is empty. Note this will | 556 // call (if any), but don't bother if the new name is empty. Note this will |
| 551 // not detect a thread name change within the same char* buffer address: we | 557 // not detect a thread name change within the same char* buffer address: we |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 // Remove begin event and do not add end event. | 591 // Remove begin event and do not add end event. |
| 586 // This will be expensive if there have been other events in the | 592 // This will be expensive if there have been other events in the |
| 587 // mean time (should be rare). | 593 // mean time (should be rare). |
| 588 logged_events_.erase(logged_events_.begin() + begin_i); | 594 logged_events_.erase(logged_events_.begin() + begin_i); |
| 589 return -1; | 595 return -1; |
| 590 } | 596 } |
| 591 } | 597 } |
| 592 ret_begin_id = static_cast<int>(logged_events_.size()); | 598 ret_begin_id = static_cast<int>(logged_events_.size()); |
| 593 logged_events_.push_back( | 599 logged_events_.push_back( |
| 594 TraceEvent(thread_id, | 600 TraceEvent(thread_id, |
| 595 now, phase, category, name, id, | 601 now, phase, category_enabled, name, id, |
| 596 arg1_name, arg1_val, | 602 num_args, arg_names, arg_types, arg_values, |
| 597 arg2_name, arg2_val, | |
| 598 flags)); | 603 flags)); |
| 599 | 604 |
| 600 if (logged_events_.size() == kTraceEventBufferSize) { | 605 if (logged_events_.size() == kTraceEventBufferSize) { |
| 601 buffer_full_callback_copy = buffer_full_callback_; | 606 buffer_full_callback_copy = buffer_full_callback_; |
| 602 } | 607 } |
| 603 } // release lock | 608 } // release lock |
| 604 | 609 |
| 605 if (!buffer_full_callback_copy.is_null()) | 610 if (!buffer_full_callback_copy.is_null()) |
| 606 buffer_full_callback_copy.Run(); | 611 buffer_full_callback_copy.Run(); |
| 607 | 612 |
| 608 return ret_begin_id; | 613 return ret_begin_id; |
| 609 } | 614 } |
| 610 | 615 |
| 611 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, | 616 void TraceLog::AddTraceEventEtw(char phase, |
| 612 const char* name, | 617 const char* name, |
| 613 const void* id, | 618 const void* id, |
| 614 const char* extra) { | 619 const char* extra) { |
| 615 #if defined(OS_WIN) | 620 #if defined(OS_WIN) |
| 616 TraceEventETWProvider::Trace(name, phase, id, extra); | 621 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 617 #endif | 622 #endif |
| 618 INTERNAL_TRACE_EVENT_ADD(phase, | 623 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, |
| 619 "ETW Trace Event", name, "id", id, "extra", TRACE_STR_COPY(extra), | 624 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); |
| 620 TRACE_EVENT_FLAG_COPY); | |
| 621 } | 625 } |
| 622 | 626 |
| 623 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, | 627 void TraceLog::AddTraceEventEtw(char phase, |
| 624 const char* name, | 628 const char* name, |
| 625 const void* id, | 629 const void* id, |
| 626 const std::string& extra) | 630 const std::string& extra) |
| 627 { | 631 { |
| 628 #if defined(OS_WIN) | 632 #if defined(OS_WIN) |
| 629 TraceEventETWProvider::Trace(name, phase, id, extra); | 633 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 630 #endif | 634 #endif |
| 631 INTERNAL_TRACE_EVENT_ADD(phase, | 635 INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, |
| 632 "ETW Trace Event", name, "id", id, "extra", extra, | 636 TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); |
| 633 TRACE_EVENT_FLAG_COPY); | |
| 634 } | 637 } |
| 635 | 638 |
| 636 int TraceLog::AddCounterEvent(const TraceCategory* category, | 639 void TraceLog::AddCounterEvent(const unsigned char* category_enabled, |
| 637 const char* name, | 640 const char* name, |
| 638 TraceID id, | 641 unsigned long long id, |
| 639 const char* value1_name, int32 value1_val, | 642 const char* value1_name, int value1_val, |
| 640 const char* value2_name, int32 value2_val, | 643 const char* value2_name, int value2_val, |
| 641 TraceEventFlags flags) { | 644 unsigned char flags) { |
| 642 return AddTraceEvent(TRACE_EVENT_PHASE_COUNTER, | 645 int num_args = value2_name ? 2 : 1; |
| 643 category, | 646 const char* arg_names[2] = {value1_name, value2_name}; |
| 644 name, | 647 unsigned char arg_types[2]; |
| 645 id, | 648 unsigned long long arg_values[2]; |
| 646 value1_name, value1_val, | 649 trace_event_internal::SetTraceValue(value1_val, &arg_types[0], |
| 647 value2_name, value2_val, | 650 &arg_values[0]); |
| 648 -1, 0, | 651 trace_event_internal::SetTraceValue(value2_val, &arg_types[1], |
| 649 flags); | 652 &arg_values[1]); |
| 653 AddTraceEvent(TRACE_EVENT_PHASE_COUNTER, |
| 654 category_enabled, |
| 655 name, |
| 656 id, |
| 657 num_args, |
| 658 arg_names, |
| 659 arg_types, |
| 660 arg_values, |
| 661 trace_event_internal::kNoThreshholdBeginId, |
| 662 trace_event_internal::kNoThresholdValue, |
| 663 flags); |
| 650 } | 664 } |
| 651 | 665 |
| 652 void TraceLog::AddClockSyncMetadataEvents() { | 666 void TraceLog::AddClockSyncMetadataEvents() { |
| 653 #if defined(OS_ANDROID) | 667 #if defined(OS_ANDROID) |
| 654 // Since Android does not support sched_setaffinity, we cannot establish clock | 668 // Since Android does not support sched_setaffinity, we cannot establish clock |
| 655 // sync unless the scheduler clock is set to global. If the trace_clock file | 669 // sync unless the scheduler clock is set to global. If the trace_clock file |
| 656 // can't be read, we will assume the kernel doesn't support tracing and do | 670 // can't be read, we will assume the kernel doesn't support tracing and do |
| 657 // nothing. | 671 // nothing. |
| 658 std::string clock_mode; | 672 std::string clock_mode; |
| 659 if (!file_util::ReadFileToString( | 673 if (!file_util::ReadFileToString( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 686 return; | 700 return; |
| 687 } | 701 } |
| 688 #endif | 702 #endif |
| 689 } | 703 } |
| 690 | 704 |
| 691 void TraceLog::AddThreadNameMetadataEvents() { | 705 void TraceLog::AddThreadNameMetadataEvents() { |
| 692 lock_.AssertAcquired(); | 706 lock_.AssertAcquired(); |
| 693 for(base::hash_map<int, std::string>::iterator it = thread_names_.begin(); | 707 for(base::hash_map<int, std::string>::iterator it = thread_names_.begin(); |
| 694 it != thread_names_.end(); | 708 it != thread_names_.end(); |
| 695 it++) { | 709 it++) { |
| 696 if (!it->second.empty()) | 710 if (!it->second.empty()) { |
| 711 int num_args = 1; |
| 712 const char* arg_name = "name"; |
| 713 unsigned char arg_type; |
| 714 unsigned long long arg_value; |
| 715 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); |
| 697 logged_events_.push_back( | 716 logged_events_.push_back( |
| 698 TraceEvent(it->first, | 717 TraceEvent(it->first, |
| 699 TimeTicks(), TRACE_EVENT_PHASE_METADATA, | 718 TimeTicks(), TRACE_EVENT_PHASE_METADATA, |
| 700 g_category_metadata, "thread_name", 0, | 719 &g_category_enabled[g_category_metadata], |
| 701 "name", it->second, | 720 "thread_name", trace_event_internal::kNoEventId, |
| 702 NULL, 0, | 721 num_args, &arg_name, &arg_type, &arg_value, |
| 703 TRACE_EVENT_FLAG_NONE)); | 722 TRACE_EVENT_FLAG_NONE)); |
| 723 } |
| 704 } | 724 } |
| 705 } | 725 } |
| 706 | 726 |
| 707 void TraceLog::DeleteForTesting() { | 727 void TraceLog::DeleteForTesting() { |
| 708 DeleteTraceLogForTesting::Delete(); | 728 DeleteTraceLogForTesting::Delete(); |
| 709 } | 729 } |
| 710 | 730 |
| 711 void TraceLog::Resurrect() { | 731 void TraceLog::Resurrect() { |
| 712 StaticMemorySingletonTraits<TraceLog>::Resurrect(); | 732 StaticMemorySingletonTraits<TraceLog>::Resurrect(); |
| 713 } | 733 } |
| 714 | 734 |
| 715 void TraceLog::SetProcessID(int process_id) { | 735 void TraceLog::SetProcessID(int process_id) { |
| 716 process_id_ = process_id; | 736 process_id_ = process_id; |
| 717 // Create a FNV hash from the process ID for XORing. | 737 // Create a FNV hash from the process ID for XORing. |
| 718 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. | 738 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. |
| 719 uint64 offset_basis = 14695981039346656037ull; | 739 unsigned long long offset_basis = 14695981039346656037ull; |
| 720 uint64 fnv_prime = 1099511628211ull; | 740 unsigned long long fnv_prime = 1099511628211ull; |
| 721 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 741 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
| 722 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 742 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
| 723 } | 743 } |
| 724 | 744 |
| 725 namespace internal { | 745 } // namespace debug |
| 746 } // namespace base |
| 726 | 747 |
| 727 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, | 748 namespace trace_event_internal { |
| 749 |
| 750 void TraceEndOnScopeClose::Initialize(const unsigned char* category_enabled, |
| 728 const char* name) { | 751 const char* name) { |
| 729 data_.category = category; | 752 data_.category_enabled = category_enabled; |
| 730 data_.name = name; | 753 data_.name = name; |
| 731 p_data_ = &data_; | 754 p_data_ = &data_; |
| 732 } | 755 } |
| 733 | 756 |
| 734 void TraceEndOnScopeClose::AddEventIfEnabled() { | 757 void TraceEndOnScopeClose::AddEventIfEnabled() { |
| 735 // Only called when p_data_ is non-null. | 758 // Only called when p_data_ is non-null. |
| 736 if (p_data_->category->enabled) { | 759 if (*p_data_->category_enabled) { |
| 737 base::debug::TraceLog::GetInstance()->AddTraceEvent( | 760 TRACE_EVENT_API_ADD_TRACE_EVENT( |
| 738 TRACE_EVENT_PHASE_END, | 761 TRACE_EVENT_PHASE_END, |
| 739 p_data_->category, | 762 p_data_->category_enabled, |
| 740 p_data_->name, kNoEventId, | 763 p_data_->name, kNoEventId, |
| 741 kNoArgName, kNoArgValue, kNoArgName, kNoArgValue, | 764 kZeroNumArgs, NULL, NULL, NULL, |
| 742 kNoThreshholdBeginId, kNoThresholdValue, TRACE_EVENT_FLAG_NONE); | 765 kNoThreshholdBeginId, kNoThresholdValue, TRACE_EVENT_FLAG_NONE); |
| 743 } | 766 } |
| 744 } | 767 } |
| 745 | 768 |
| 746 void TraceEndOnScopeCloseThreshold::Initialize(const TraceCategory* category, | 769 void TraceEndOnScopeCloseThreshold::Initialize( |
| 747 const char* name, | 770 const unsigned char* category_enabled, |
| 748 int threshold_begin_id, | 771 const char* name, |
| 749 int64 threshold) { | 772 int threshold_begin_id, |
| 750 data_.category = category; | 773 long long threshold) { |
| 774 data_.category_enabled = category_enabled; |
| 751 data_.name = name; | 775 data_.name = name; |
| 752 data_.threshold_begin_id = threshold_begin_id; | 776 data_.threshold_begin_id = threshold_begin_id; |
| 753 data_.threshold = threshold; | 777 data_.threshold = threshold; |
| 754 p_data_ = &data_; | 778 p_data_ = &data_; |
| 755 } | 779 } |
| 756 | 780 |
| 757 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() { | 781 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() { |
| 758 // Only called when p_data_ is non-null. | 782 // Only called when p_data_ is non-null. |
| 759 if (p_data_->category->enabled) { | 783 if (*p_data_->category_enabled) { |
| 760 base::debug::TraceLog::GetInstance()->AddTraceEvent( | 784 TRACE_EVENT_API_ADD_TRACE_EVENT( |
| 761 TRACE_EVENT_PHASE_END, | 785 TRACE_EVENT_PHASE_END, |
| 762 p_data_->category, | 786 p_data_->category_enabled, |
| 763 p_data_->name, kNoEventId, | 787 p_data_->name, kNoEventId, |
| 764 kNoArgName, kNoArgValue, kNoArgName, kNoArgValue, | 788 kZeroNumArgs, NULL, NULL, NULL, |
| 765 p_data_->threshold_begin_id, p_data_->threshold, | 789 p_data_->threshold_begin_id, p_data_->threshold, |
| 766 TRACE_EVENT_FLAG_NONE); | 790 TRACE_EVENT_FLAG_NONE); |
| 767 } | 791 } |
| 768 } | 792 } |
| 769 | 793 |
| 770 } // namespace internal | 794 } // namespace trace_event_internal |
| 771 | |
| 772 } // namespace debug | |
| 773 } // namespace base | |
| OLD | NEW |