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 | 5 |
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
8 | 8 |
9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
10 | 10 |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/callback.h" | 14 #include "base/callback.h" |
15 #include "base/hash_tables.h" | 15 #include "base/hash_tables.h" |
16 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
17 #include "base/observer_list.h" | 17 #include "base/observer_list.h" |
18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
19 #include "base/synchronization/condition_variable.h" | |
19 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
20 #include "base/timer.h" | 21 #include "base/timer.h" |
21 | 22 |
22 // Older style trace macros with explicit id and extra data | 23 // Older style trace macros with explicit id and extra data |
23 // Only these macros result in publishing data to ETW as currently implemented. | 24 // Only these macros result in publishing data to ETW as currently implemented. |
24 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | 25 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
25 base::debug::TraceLog::AddTraceEventEtw( \ | 26 base::debug::TraceLog::AddTraceEventEtw( \ |
26 TRACE_EVENT_PHASE_BEGIN, \ | 27 TRACE_EVENT_PHASE_BEGIN, \ |
27 name, reinterpret_cast<const void*>(id), extra) | 28 name, reinterpret_cast<const void*>(id), extra) |
28 | 29 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 void AppendAsJSON(std::string* out) const; | 83 void AppendAsJSON(std::string* out) const; |
83 | 84 |
84 TimeTicks timestamp() const { return timestamp_; } | 85 TimeTicks timestamp() const { return timestamp_; } |
85 | 86 |
86 // Exposed for unittesting: | 87 // Exposed for unittesting: |
87 | 88 |
88 const base::RefCountedString* parameter_copy_storage() const { | 89 const base::RefCountedString* parameter_copy_storage() const { |
89 return parameter_copy_storage_.get(); | 90 return parameter_copy_storage_.get(); |
90 } | 91 } |
91 | 92 |
93 const unsigned char* category_enabled() const { return category_enabled_; } | |
92 const char* name() const { return name_; } | 94 const char* name() const { return name_; } |
93 | 95 |
94 private: | 96 private: |
95 // Note: these are ordered by size (largest first) for optimal packing. | 97 // Note: these are ordered by size (largest first) for optimal packing. |
96 TimeTicks timestamp_; | 98 TimeTicks timestamp_; |
97 // id_ can be used to store phase-specific data. | 99 // id_ can be used to store phase-specific data. |
98 unsigned long long id_; | 100 unsigned long long id_; |
99 TraceValue arg_values_[kTraceMaxNumArgs]; | 101 TraceValue arg_values_[kTraceMaxNumArgs]; |
100 const char* arg_names_[kTraceMaxNumArgs]; | 102 const char* arg_names_[kTraceMaxNumArgs]; |
101 const unsigned char* category_enabled_; | 103 const unsigned char* category_enabled_; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 void Finish(); | 149 void Finish(); |
148 | 150 |
149 private: | 151 private: |
150 OutputCallback output_callback_; | 152 OutputCallback output_callback_; |
151 bool append_comma_; | 153 bool append_comma_; |
152 }; | 154 }; |
153 | 155 |
154 | 156 |
155 class BASE_EXPORT TraceLog { | 157 class BASE_EXPORT TraceLog { |
156 public: | 158 public: |
159 // Notification is a mask of one or more of the following events. | |
160 enum Notification { | |
161 // The trace buffer does not flush dynamically, so when it fills up, | |
162 // subsequent trace events will be dropped. This callback is generated when | |
163 // the trace buffer is full. The callback must be thread safe. | |
164 TRACE_BUFFER_FULL = 1 << 0, | |
165 // A subscribed trace-event occurred. | |
166 EVENT_WATCH_NOTIFICATION = 1 << 1 | |
167 }; | |
168 | |
157 static TraceLog* GetInstance(); | 169 static TraceLog* GetInstance(); |
158 | 170 |
159 // Get set of known categories. This can change as new code paths are reached. | 171 // Get set of known categories. This can change as new code paths are reached. |
160 // The known categories are inserted into |categories|. | 172 // The known categories are inserted into |categories|. |
161 void GetKnownCategories(std::vector<std::string>* categories); | 173 void GetKnownCategories(std::vector<std::string>* categories); |
162 | 174 |
163 // Enable tracing for provided list of categories. If tracing is already | 175 // Enable tracing for provided list of categories. If tracing is already |
164 // enabled, this method does nothing -- changing categories during trace is | 176 // enabled, this method does nothing -- changing categories during trace is |
165 // not supported. | 177 // not supported. |
166 // If both included_categories and excluded_categories are empty, | 178 // If both included_categories and excluded_categories are empty, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 // still false at this point TRACE macros will still be capturing | 218 // still false at this point TRACE macros will still be capturing |
207 // data. However, trace macros and methods called within the observer will | 219 // data. However, trace macros and methods called within the observer will |
208 // deadlock. | 220 // deadlock. |
209 virtual void OnTraceLogWillDisable() { } | 221 virtual void OnTraceLogWillDisable() { } |
210 }; | 222 }; |
211 void AddEnabledStateObserver(EnabledStateChangedObserver* listener); | 223 void AddEnabledStateObserver(EnabledStateChangedObserver* listener); |
212 void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener); | 224 void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener); |
213 | 225 |
214 float GetBufferPercentFull() const; | 226 float GetBufferPercentFull() const; |
215 | 227 |
216 // When enough events are collected, they are handed (in bulk) to | 228 // Set the thread-safe notification callback. The callback can occur at any |
217 // the output callback. If no callback is set, the output will be | 229 // time. After calling SetNotificationCallback(NotificationCallback()) to |
piman
2012/08/29 16:50:07
nit: please note (because it's not obvious) that t
jbates
2012/08/29 21:14:12
Done.
| |
218 // silently dropped. The callback must be thread safe. The string format is | 230 // clear the callback, it is guaranteed that the old callback will no longer |
231 // be called. Warning: it is possible for the old callback to be called during | |
232 // a call to SetNotificationCallback. | |
233 typedef base::Callback<void(int)> NotificationCallback; | |
234 void SetNotificationCallback(const NotificationCallback& cb); | |
235 | |
236 // Flush all collected events to the given output callback. The callback will | |
237 // be called one or more times with IPC-bite-size chunks. The string format is | |
219 // undefined. Use TraceResultBuffer to convert one or more trace strings to | 238 // undefined. Use TraceResultBuffer to convert one or more trace strings to |
220 // JSON. | 239 // JSON. |
221 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> | 240 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> |
222 OutputCallback; | 241 OutputCallback; |
223 void SetOutputCallback(const OutputCallback& cb); | 242 void Flush(const OutputCallback& cb); |
224 | |
225 // The trace buffer does not flush dynamically, so when it fills up, | |
226 // subsequent trace events will be dropped. This callback is generated when | |
227 // the trace buffer is full. The callback must be thread safe. | |
228 typedef base::Callback<void(void)> BufferFullCallback; | |
229 void SetBufferFullCallback(const BufferFullCallback& cb); | |
230 | |
231 // Flushes all logged data to the callback. | |
232 void Flush(); | |
233 | 243 |
234 // Called by TRACE_EVENT* macros, don't call this directly. | 244 // Called by TRACE_EVENT* macros, don't call this directly. |
235 static const unsigned char* GetCategoryEnabled(const char* name); | 245 static const unsigned char* GetCategoryEnabled(const char* name); |
236 static const char* GetCategoryName(const unsigned char* category_enabled); | 246 static const char* GetCategoryName(const unsigned char* category_enabled); |
237 | 247 |
238 // Called by TRACE_EVENT* macros, don't call this directly. | 248 // Called by TRACE_EVENT* macros, don't call this directly. |
239 // Returns the index in the internal vector of the event if it was added, or | 249 // Returns the index in the internal vector of the event if it was added, or |
240 // -1 if the event was not added. | 250 // -1 if the event was not added. |
241 // On end events, the return value of the begin event can be specified along | 251 // On end events, the return value of the begin event can be specified along |
242 // with a threshold in microseconds. If the elapsed time between begin and end | 252 // with a threshold in microseconds. If the elapsed time between begin and end |
(...skipping 13 matching lines...) Expand all Loading... | |
256 unsigned char flags); | 266 unsigned char flags); |
257 static void AddTraceEventEtw(char phase, | 267 static void AddTraceEventEtw(char phase, |
258 const char* name, | 268 const char* name, |
259 const void* id, | 269 const void* id, |
260 const char* extra); | 270 const char* extra); |
261 static void AddTraceEventEtw(char phase, | 271 static void AddTraceEventEtw(char phase, |
262 const char* name, | 272 const char* name, |
263 const void* id, | 273 const void* id, |
264 const std::string& extra); | 274 const std::string& extra); |
265 | 275 |
276 // For every matching event, a notification will be fired. NOTE: the | |
277 // notification will fire for each matching event that has already occurred | |
278 // since tracing was started (including before tracing if the process was | |
279 // started with tracing turned on). | |
280 void SetWatchEvent(const std::string& category_name, | |
281 const std::string& event_name); | |
282 // Cancel the watch event. If tracing is enabled, this may race with the | |
283 // watch event notification firing. | |
284 void CancelWatchEvent(); | |
285 | |
266 int process_id() const { return process_id_; } | 286 int process_id() const { return process_id_; } |
267 | 287 |
268 // Exposed for unittesting: | 288 // Exposed for unittesting: |
269 | 289 |
270 // Allows deleting our singleton instance. | 290 // Allows deleting our singleton instance. |
271 static void DeleteForTesting(); | 291 static void DeleteForTesting(); |
272 | 292 |
273 // Allows resurrecting our singleton instance post-AtExit processing. | 293 // Allows resurrecting our singleton instance post-AtExit processing. |
274 static void Resurrect(); | 294 static void Resurrect(); |
275 | 295 |
276 // Allow tests to inspect TraceEvents. | 296 // Allow tests to inspect TraceEvents. |
277 size_t GetEventsSize() const { return logged_events_.size(); } | 297 size_t GetEventsSize() const { return logged_events_.size(); } |
278 const TraceEvent& GetEventAt(size_t index) const { | 298 const TraceEvent& GetEventAt(size_t index) const { |
279 DCHECK(index < logged_events_.size()); | 299 DCHECK(index < logged_events_.size()); |
280 return logged_events_[index]; | 300 return logged_events_[index]; |
281 } | 301 } |
282 | 302 |
283 void SetProcessID(int process_id); | 303 void SetProcessID(int process_id); |
284 | 304 |
285 private: | 305 private: |
286 // This allows constructor and destructor to be private and usable only | 306 // This allows constructor and destructor to be private and usable only |
287 // by the Singleton class. | 307 // by the Singleton class. |
288 friend struct StaticMemorySingletonTraits<TraceLog>; | 308 friend struct StaticMemorySingletonTraits<TraceLog>; |
289 | 309 |
310 // Helper class for managing notification_thread_count_ and running | |
311 // notification callbacks. This is very similar to a reader-writer lock, but | |
312 // shares the lock with TraceLog and manages the notification flags. | |
313 class NotificationHelper { | |
314 public: | |
315 inline NotificationHelper(TraceLog* trace_log); | |
316 inline ~NotificationHelper(); | |
317 | |
318 // Called only while TraceLog::lock_ is held. | |
319 inline void AddNotificationWhileLocked(int notification); | |
320 | |
321 // Called only while TraceLog::lock_ is NOT held. | |
322 inline void SendNotificationIfAny(); | |
323 | |
324 private: | |
325 TraceLog* trace_log_; | |
326 NotificationCallback callback_copy_; | |
327 int notification_; | |
328 }; | |
329 | |
290 TraceLog(); | 330 TraceLog(); |
291 ~TraceLog(); | 331 ~TraceLog(); |
292 const unsigned char* GetCategoryEnabledInternal(const char* name); | 332 const unsigned char* GetCategoryEnabledInternal(const char* name); |
293 void AddThreadNameMetadataEvents(); | 333 void AddThreadNameMetadataEvents(); |
294 void AddClockSyncMetadataEvents(); | 334 void AddClockSyncMetadataEvents(); |
295 | 335 |
296 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 336 // TODO(nduca): switch to per-thread trace buffers to reduce thread |
297 // synchronization. | 337 // synchronization. |
298 Lock lock_; | 338 Lock lock_; |
299 bool enabled_; | 339 bool enabled_; |
300 OutputCallback output_callback_; | 340 base::ConditionVariable notification_condition_; |
301 BufferFullCallback buffer_full_callback_; | 341 NotificationCallback notification_callback_; |
342 // Number of threads that are have a copy of the notification callback. | |
piman
2012/08/29 16:50:07
nit: "that are have" typo?
jbates
2012/08/29 21:14:12
Done. Changed to "are belong to".
| |
343 int notification_thread_count_; | |
302 std::vector<TraceEvent> logged_events_; | 344 std::vector<TraceEvent> logged_events_; |
303 std::vector<std::string> included_categories_; | 345 std::vector<std::string> included_categories_; |
304 std::vector<std::string> excluded_categories_; | 346 std::vector<std::string> excluded_categories_; |
305 bool dispatching_to_observer_list_; | 347 bool dispatching_to_observer_list_; |
306 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; | 348 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; |
307 | 349 |
308 base::hash_map<int, std::string> thread_names_; | 350 base::hash_map<int, std::string> thread_names_; |
309 | 351 |
310 // XORed with TraceID to make it unlikely to collide with other processes. | 352 // XORed with TraceID to make it unlikely to collide with other processes. |
311 unsigned long long process_id_hash_; | 353 unsigned long long process_id_hash_; |
312 | 354 |
313 int process_id_; | 355 int process_id_; |
314 | 356 |
357 // Allow tests to wake up when certain events occur. | |
358 const unsigned char* watch_category_; | |
359 std::string watch_event_name_; | |
360 | |
315 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 361 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
316 }; | 362 }; |
317 | 363 |
318 } // namespace debug | 364 } // namespace debug |
319 } // namespace base | 365 } // namespace base |
320 | 366 |
321 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 367 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |