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 and from any thread. WARNING: It is possible for the previously set |
218 // silently dropped. The callback must be thread safe. The string format is | 230 // callback to be called during OR AFTER a call to SetNotificationCallback. |
| 231 // Therefore, the target of the callback must either be a global function, |
| 232 // ref-counted object or a LazyInstance with Leaky traits (or equivalent). |
| 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 explicit NotificationHelper(TraceLog* trace_log); |
| 316 inline ~NotificationHelper(); |
| 317 |
| 318 // Called only while TraceLog::lock_ is held. This ORs the given |
| 319 // notification with any existing notifcations. |
| 320 inline void AddNotificationWhileLocked(int notification); |
| 321 |
| 322 // Called only while TraceLog::lock_ is NOT held. If there are any pending |
| 323 // notifications from previous calls to AddNotificationWhileLocked, this |
| 324 // will call the NotificationCallback. |
| 325 inline void SendNotificationIfAny(); |
| 326 |
| 327 private: |
| 328 TraceLog* trace_log_; |
| 329 NotificationCallback callback_copy_; |
| 330 int notification_; |
| 331 }; |
| 332 |
290 TraceLog(); | 333 TraceLog(); |
291 ~TraceLog(); | 334 ~TraceLog(); |
292 const unsigned char* GetCategoryEnabledInternal(const char* name); | 335 const unsigned char* GetCategoryEnabledInternal(const char* name); |
293 void AddThreadNameMetadataEvents(); | 336 void AddThreadNameMetadataEvents(); |
294 void AddClockSyncMetadataEvents(); | 337 void AddClockSyncMetadataEvents(); |
295 | 338 |
296 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 339 // TODO(nduca): switch to per-thread trace buffers to reduce thread |
297 // synchronization. | 340 // synchronization. |
| 341 // This lock protects TraceLog member accesses from arbitrary threads. |
298 Lock lock_; | 342 Lock lock_; |
299 bool enabled_; | 343 bool enabled_; |
300 OutputCallback output_callback_; | 344 NotificationCallback notification_callback_; |
301 BufferFullCallback buffer_full_callback_; | |
302 std::vector<TraceEvent> logged_events_; | 345 std::vector<TraceEvent> logged_events_; |
303 std::vector<std::string> included_categories_; | 346 std::vector<std::string> included_categories_; |
304 std::vector<std::string> excluded_categories_; | 347 std::vector<std::string> excluded_categories_; |
305 bool dispatching_to_observer_list_; | 348 bool dispatching_to_observer_list_; |
306 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; | 349 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; |
307 | 350 |
308 base::hash_map<int, std::string> thread_names_; | 351 base::hash_map<int, std::string> thread_names_; |
309 | 352 |
310 // XORed with TraceID to make it unlikely to collide with other processes. | 353 // XORed with TraceID to make it unlikely to collide with other processes. |
311 unsigned long long process_id_hash_; | 354 unsigned long long process_id_hash_; |
312 | 355 |
313 int process_id_; | 356 int process_id_; |
314 | 357 |
| 358 // Allow tests to wake up when certain events occur. |
| 359 const unsigned char* watch_category_; |
| 360 std::string watch_event_name_; |
| 361 |
315 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 362 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
316 }; | 363 }; |
317 | 364 |
318 } // namespace debug | 365 } // namespace debug |
319 } // namespace base | 366 } // namespace base |
320 | 367 |
321 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 368 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
OLD | NEW |