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

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

Issue 22962004: Thread-local trace-event buffers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update browser_shutdown_profile_dumper Created 7 years, 3 months 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
« no previous file with comments | « no previous file | base/debug/trace_event_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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 <stack> 9 #include <stack>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/atomicops.h"
13 #include "base/callback.h" 14 #include "base/callback.h"
14 #include "base/containers/hash_tables.h" 15 #include "base/containers/hash_tables.h"
15 #include "base/gtest_prod_util.h" 16 #include "base/gtest_prod_util.h"
16 #include "base/memory/ref_counted_memory.h" 17 #include "base/memory/ref_counted_memory.h"
17 #include "base/memory/scoped_vector.h" 18 #include "base/memory/scoped_vector.h"
18 #include "base/observer_list.h" 19 #include "base/observer_list.h"
19 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
20 #include "base/synchronization/condition_variable.h" 21 #include "base/synchronization/condition_variable.h"
21 #include "base/synchronization/lock.h" 22 #include "base/synchronization/lock.h"
22 #include "base/threading/thread.h" 23 #include "base/threading/thread.h"
24 #include "base/threading/thread_local.h"
23 #include "base/timer/timer.h" 25 #include "base/timer/timer.h"
24 26
25 // Older style trace macros with explicit id and extra data 27 // Older style trace macros with explicit id and extra data
26 // Only these macros result in publishing data to ETW as currently implemented. 28 // Only these macros result in publishing data to ETW as currently implemented.
27 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ 29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
28 base::debug::TraceLog::AddTraceEventEtw( \ 30 base::debug::TraceLog::AddTraceEventEtw( \
29 TRACE_EVENT_PHASE_BEGIN, \ 31 TRACE_EVENT_PHASE_BEGIN, \
30 name, reinterpret_cast<const void*>(id), extra) 32 name, reinterpret_cast<const void*>(id), extra)
31 33
32 #define TRACE_EVENT_END_ETW(name, id, extra) \ 34 #define TRACE_EVENT_END_ETW(name, id, extra) \
33 base::debug::TraceLog::AddTraceEventEtw( \ 35 base::debug::TraceLog::AddTraceEventEtw( \
34 TRACE_EVENT_PHASE_END, \ 36 TRACE_EVENT_PHASE_END, \
35 name, reinterpret_cast<const void*>(id), extra) 37 name, reinterpret_cast<const void*>(id), extra)
36 38
37 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ 39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
38 base::debug::TraceLog::AddTraceEventEtw( \ 40 base::debug::TraceLog::AddTraceEventEtw( \
39 TRACE_EVENT_PHASE_INSTANT, \ 41 TRACE_EVENT_PHASE_INSTANT, \
40 name, reinterpret_cast<const void*>(id), extra) 42 name, reinterpret_cast<const void*>(id), extra)
41 43
42 template <typename Type> 44 template <typename Type>
43 struct DefaultSingletonTraits; 45 struct DefaultSingletonTraits;
44 46
47 #if defined(COMPILER_GCC)
48 namespace BASE_HASH_NAMESPACE {
49 template <>
50 struct hash<base::MessageLoop*> {
51 std::size_t operator()(base::MessageLoop* value) const {
52 return reinterpret_cast<std::size_t>(value);
53 }
54 };
55 } // BASE_HASH_NAMESPACE
56 #endif
57
45 namespace base { 58 namespace base {
46 59
47 class WaitableEvent; 60 class WaitableEvent;
61 class MessageLoop;
48 62
49 namespace debug { 63 namespace debug {
50 64
51 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
52 // class must implement this interface. 66 // class must implement this interface.
53 class ConvertableToTraceFormat { 67 class ConvertableToTraceFormat {
54 public: 68 public:
55 virtual ~ConvertableToTraceFormat() {} 69 virtual ~ConvertableToTraceFormat() {}
56 70
57 // Append the class info to the provided |out| string. The appended 71 // Append the class info to the provided |out| string. The appended
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 std::string* out); 117 std::string* out);
104 void AppendAsJSON(std::string* out) const; 118 void AppendAsJSON(std::string* out) const;
105 void AppendPrettyPrinted(std::ostringstream* out) const; 119 void AppendPrettyPrinted(std::ostringstream* out) const;
106 120
107 static void AppendValueAsJSON(unsigned char type, 121 static void AppendValueAsJSON(unsigned char type,
108 TraceValue value, 122 TraceValue value,
109 std::string* out); 123 std::string* out);
110 124
111 TimeTicks timestamp() const { return timestamp_; } 125 TimeTicks timestamp() const { return timestamp_; }
112 TimeTicks thread_timestamp() const { return thread_timestamp_; } 126 TimeTicks thread_timestamp() const { return thread_timestamp_; }
127 char phase() const { return phase_; }
128 int thread_id() const { return thread_id_; }
113 129
114 // Exposed for unittesting: 130 // Exposed for unittesting:
115 131
116 const base::RefCountedString* parameter_copy_storage() const { 132 const base::RefCountedString* parameter_copy_storage() const {
117 return parameter_copy_storage_.get(); 133 return parameter_copy_storage_.get();
118 } 134 }
119 135
120 const unsigned char* category_group_enabled() const { 136 const unsigned char* category_group_enabled() const {
121 return category_group_enabled_; 137 return category_group_enabled_;
122 } 138 }
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 RECORD_UNTIL_FULL = 1 << 0, 305 RECORD_UNTIL_FULL = 1 << 0,
290 306
291 // Record until the user ends the trace. The trace buffer is a fixed size 307 // Record until the user ends the trace. The trace buffer is a fixed size
292 // and we use it as a ring buffer during recording. 308 // and we use it as a ring buffer during recording.
293 RECORD_CONTINUOUSLY = 1 << 1, 309 RECORD_CONTINUOUSLY = 1 << 1,
294 310
295 // Enable the sampling profiler. 311 // Enable the sampling profiler.
296 ENABLE_SAMPLING = 1 << 2, 312 ENABLE_SAMPLING = 1 << 2,
297 313
298 // Echo to console. Events are discarded. 314 // Echo to console. Events are discarded.
299 ECHO_TO_CONSOLE = 1 << 3 315 ECHO_TO_CONSOLE = 1 << 3,
300 }; 316 };
301 317
302 static TraceLog* GetInstance(); 318 static TraceLog* GetInstance();
303 319
304 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if 320 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if
305 // the string does not provide valid options. 321 // the string does not provide valid options.
306 static Options TraceOptionsFromString(const std::string& str); 322 static Options TraceOptionsFromString(const std::string& str);
307 323
308 // Get set of known category groups. This can change as new code paths are 324 // Get set of known category groups. This can change as new code paths are
309 // reached. The known category groups are inserted into |category_groups|. 325 // reached. The known category groups are inserted into |category_groups|.
310 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); 326 void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
311 327
312 // Retrieves the current CategoryFilter. 328 // Retrieves the current CategoryFilter.
313 const CategoryFilter& GetCurrentCategoryFilter(); 329 const CategoryFilter& GetCurrentCategoryFilter();
314 330
315 Options trace_options() const { return trace_options_; } 331 Options trace_options() const {
332 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_));
333 }
316 334
317 // Enables tracing. See CategoryFilter comments for details 335 // Enables tracing. See CategoryFilter comments for details
318 // on how to control what categories will be traced. 336 // on how to control what categories will be traced.
319 void SetEnabled(const CategoryFilter& category_filter, Options options); 337 void SetEnabled(const CategoryFilter& category_filter, Options options);
320 338
321 // Disable tracing for all categories. 339 // Disable tracing for all categories.
322 void SetDisabled(); 340 void SetDisabled();
323 bool IsEnabled() { return !!enable_count_; } 341 bool IsEnabled() { return !!enable_count_; }
324 342
325 // The number of times we have begun recording traces. If tracing is off, 343 // The number of times we have begun recording traces. If tracing is off,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 const char* name, 389 const char* name,
372 unsigned long long id, 390 unsigned long long id,
373 int num_args, 391 int num_args,
374 const char* const arg_names[], 392 const char* const arg_names[],
375 const unsigned char arg_types[], 393 const unsigned char arg_types[],
376 const unsigned long long arg_values[], 394 const unsigned long long arg_values[],
377 unsigned char flags); 395 unsigned char flags);
378 void SetEventCallback(EventCallback cb); 396 void SetEventCallback(EventCallback cb);
379 397
380 // Flush all collected events to the given output callback. The callback will 398 // Flush all collected events to the given output callback. The callback will
381 // be called one or more times with IPC-bite-size chunks. The string format is 399 // be called one or more times either synchronously or asynchronously from
400 // the current thread with IPC-bite-size chunks. The string format is
382 // undefined. Use TraceResultBuffer to convert one or more trace strings to 401 // undefined. Use TraceResultBuffer to convert one or more trace strings to
383 // JSON. 402 // JSON. The callback can be null if the caller doesn't want any data.
384 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> 403 // Due to the implementation of thread-local buffers, flush can't be
385 OutputCallback; 404 // done when tracing is enabled. If called when tracing is enabled, the
405 // callback will be called directly with (empty_string, false) to indicate
406 // the end of this unsuccessful flush.
407 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
408 bool has_more_events)> OutputCallback;
386 void Flush(const OutputCallback& cb); 409 void Flush(const OutputCallback& cb);
387 410
388 // Called by TRACE_EVENT* macros, don't call this directly. 411 // Called by TRACE_EVENT* macros, don't call this directly.
389 // The name parameter is a category group for example: 412 // The name parameter is a category group for example:
390 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") 413 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
391 static const unsigned char* GetCategoryGroupEnabled(const char* name); 414 static const unsigned char* GetCategoryGroupEnabled(const char* name);
392 static const char* GetCategoryGroupName( 415 static const char* GetCategoryGroupName(
393 const unsigned char* category_group_enabled); 416 const unsigned char* category_group_enabled);
394 417
395 // Called by TRACE_EVENT* macros, don't call this directly. 418 // Called by TRACE_EVENT* macros, don't call this directly.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // notifications from previous calls to AddNotificationWhileLocked, this 545 // notifications from previous calls to AddNotificationWhileLocked, this
523 // will call the NotificationCallback. 546 // will call the NotificationCallback.
524 inline void SendNotificationIfAny(); 547 inline void SendNotificationIfAny();
525 548
526 private: 549 private:
527 TraceLog* trace_log_; 550 TraceLog* trace_log_;
528 NotificationCallback callback_copy_; 551 NotificationCallback callback_copy_;
529 int notification_; 552 int notification_;
530 }; 553 };
531 554
555 class ThreadLocalEventBuffer;
556
532 TraceLog(); 557 TraceLog();
533 ~TraceLog(); 558 ~TraceLog();
534 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); 559 const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
535 void AddMetadataEvents(); 560 void AddMetadataEvents();
536 561
537 #if defined(OS_ANDROID) 562 #if defined(OS_ANDROID)
538 void SendToATrace(char phase, 563 void SendToATrace(char phase,
539 const char* category_group, 564 const char* category_group,
540 const char* name, 565 const char* name,
541 unsigned long long id, 566 unsigned long long id,
542 int num_args, 567 int num_args,
543 const char** arg_names, 568 const char** arg_names,
544 const unsigned char* arg_types, 569 const unsigned char* arg_types,
545 const unsigned long long* arg_values, 570 const unsigned long long* arg_values,
546 scoped_ptr<ConvertableToTraceFormat> convertable_values[], 571 scoped_ptr<ConvertableToTraceFormat> convertable_values[],
547 unsigned char flags); 572 unsigned char flags);
548 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); 573 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled);
549 #endif 574 #endif
550 575
551 TraceBuffer* GetTraceBuffer(); 576 TraceBuffer* GetTraceBuffer();
552 577
553 // TODO(nduca): switch to per-thread trace buffers to reduce thread 578 void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event);
554 // synchronization. 579 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier);
580 // |flush_count| is used in the following callbacks to check if the callback
581 // is called for the current flush.
582 void FlushCurrentThread(int flush_count);
583 void FinishFlush(int flush_count);
584 void OnFlushTimeout(int flush_count);
585
555 // This lock protects TraceLog member accesses from arbitrary threads. 586 // This lock protects TraceLog member accesses from arbitrary threads.
556 Lock lock_; 587 Lock lock_;
588 int locked_line_;
557 int enable_count_; 589 int enable_count_;
558 int num_traces_recorded_; 590 int num_traces_recorded_;
591 subtle::AtomicWord /* bool */ buffer_is_full_;
559 NotificationCallback notification_callback_; 592 NotificationCallback notification_callback_;
560 scoped_ptr<TraceBuffer> logged_events_; 593 scoped_ptr<TraceBuffer> logged_events_;
561 EventCallback event_callback_; 594 subtle::AtomicWord /* EventCallback */ event_callback_;
562 bool dispatching_to_observer_list_; 595 bool dispatching_to_observer_list_;
563 std::vector<EnabledStateObserver*> enabled_state_observer_list_; 596 std::vector<EnabledStateObserver*> enabled_state_observer_list_;
564 597
565 std::string process_name_; 598 std::string process_name_;
566 base::hash_map<int, std::string> process_labels_; 599 base::hash_map<int, std::string> process_labels_;
567 int process_sort_index_; 600 int process_sort_index_;
568 base::hash_map<int, int> thread_sort_indices_; 601 base::hash_map<int, int> thread_sort_indices_;
602 base::hash_map<int, std::string> thread_names_;
569 603
570 base::hash_map<int, std::string> thread_names_; 604 // The following two maps are used only when ECHO_TO_CONSOLE.
571 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; 605 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
572 base::hash_map<std::string, int> thread_colors_; 606 base::hash_map<std::string, int> thread_colors_;
573 607
574 // XORed with TraceID to make it unlikely to collide with other processes. 608 // XORed with TraceID to make it unlikely to collide with other processes.
575 unsigned long long process_id_hash_; 609 unsigned long long process_id_hash_;
576 610
577 int process_id_; 611 int process_id_;
578 612
579 TimeDelta time_offset_; 613 TimeDelta time_offset_;
580 614
581 // Allow tests to wake up when certain events occur. 615 // Allow tests to wake up when certain events occur.
582 const unsigned char* watch_category_; 616 subtle::AtomicWord /* const unsigned char* */ watch_category_;
583 std::string watch_event_name_; 617 std::string watch_event_name_;
584 618
585 Options trace_options_; 619 subtle::AtomicWord /* Options */ trace_options_;
586 620
587 // Sampling thread handles. 621 // Sampling thread handles.
588 scoped_ptr<TraceSamplingThread> sampling_thread_; 622 scoped_ptr<TraceSamplingThread> sampling_thread_;
589 PlatformThreadHandle sampling_thread_handle_; 623 PlatformThreadHandle sampling_thread_handle_;
590 624
591 CategoryFilter category_filter_; 625 CategoryFilter category_filter_;
592 626
627 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
628
629 // Contains the message loops of threads that have had at least one event
630 // added into the local event buffer. Not using MessageLoopProxy because we
631 // need to know the life time of the message loops.
632 base::hash_set<MessageLoop*> thread_message_loops_;
633
634 // Set when asynchronous Flush is in progress.
635 OutputCallback flush_output_callback_;
636 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
637 int flush_count_;
638
593 DISALLOW_COPY_AND_ASSIGN(TraceLog); 639 DISALLOW_COPY_AND_ASSIGN(TraceLog);
594 }; 640 };
595 641
596 } // namespace debug 642 } // namespace debug
597 } // namespace base 643 } // namespace base
598 644
599 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ 645 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_
OLDNEW
« no previous file with comments | « no previous file | base/debug/trace_event_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698