Index: base/debug/trace_event_impl.h |
diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h |
index e1bf148581627d1be976015380ca16f3700c6be8..4967c10ead58d260abe66d2550baf095f15a88cf 100644 |
--- a/base/debug/trace_event_impl.h |
+++ b/base/debug/trace_event_impl.h |
@@ -10,6 +10,7 @@ |
#include <string> |
#include <vector> |
+#include "base/atomicops.h" |
#include "base/callback.h" |
#include "base/containers/hash_tables.h" |
#include "base/gtest_prod_util.h" |
@@ -20,6 +21,7 @@ |
#include "base/synchronization/condition_variable.h" |
#include "base/synchronization/lock.h" |
#include "base/threading/thread.h" |
+#include "base/threading/thread_local.h" |
#include "base/timer/timer.h" |
// Older style trace macros with explicit id and extra data |
@@ -42,9 +44,21 @@ |
template <typename Type> |
struct DefaultSingletonTraits; |
+#if defined(COMPILER_GCC) |
+namespace BASE_HASH_NAMESPACE { |
+template <> |
+struct hash<base::MessageLoop*> { |
+ std::size_t operator()(base::MessageLoop* value) const { |
+ return reinterpret_cast<std::size_t>(value); |
+ } |
+}; |
+} // BASE_HASH_NAMESPACE |
+#endif |
+ |
namespace base { |
class WaitableEvent; |
+class MessageLoop; |
namespace debug { |
@@ -110,6 +124,8 @@ class BASE_EXPORT TraceEvent { |
TimeTicks timestamp() const { return timestamp_; } |
TimeTicks thread_timestamp() const { return thread_timestamp_; } |
+ char phase() const { return phase_; } |
+ int thread_id() const { return thread_id_; } |
// Exposed for unittesting: |
@@ -296,7 +312,7 @@ class BASE_EXPORT TraceLog { |
ENABLE_SAMPLING = 1 << 2, |
// Echo to console. Events are discarded. |
- ECHO_TO_CONSOLE = 1 << 3 |
+ ECHO_TO_CONSOLE = 1 << 3, |
}; |
static TraceLog* GetInstance(); |
@@ -312,7 +328,9 @@ class BASE_EXPORT TraceLog { |
// Retrieves the current CategoryFilter. |
const CategoryFilter& GetCurrentCategoryFilter(); |
- Options trace_options() const { return trace_options_; } |
+ Options trace_options() const { |
+ return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); |
+ } |
// Enables tracing. See CategoryFilter comments for details |
// on how to control what categories will be traced. |
@@ -378,11 +396,16 @@ class BASE_EXPORT TraceLog { |
void SetEventCallback(EventCallback cb); |
// Flush all collected events to the given output callback. The callback will |
- // be called one or more times with IPC-bite-size chunks. The string format is |
+ // be called one or more times either synchronously or asynchronously from |
+ // the current thread with IPC-bite-size chunks. The string format is |
// undefined. Use TraceResultBuffer to convert one or more trace strings to |
- // JSON. |
- typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> |
- OutputCallback; |
+ // JSON. The callback can be null if the caller doesn't want any data. |
+ // Due to the implementation of thread-local buffers, flush can't be |
+ // done when tracing is enabled. If called when tracing is enabled, the |
+ // callback will be called directly with (empty_string, false) to indicate |
+ // the end of this unsuccessful flush. |
+ typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, |
+ bool has_more_events)> OutputCallback; |
void Flush(const OutputCallback& cb); |
// Called by TRACE_EVENT* macros, don't call this directly. |
@@ -529,6 +552,8 @@ class BASE_EXPORT TraceLog { |
int notification_; |
}; |
+ class ThreadLocalEventBuffer; |
+ |
TraceLog(); |
~TraceLog(); |
const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
@@ -550,15 +575,23 @@ class BASE_EXPORT TraceLog { |
TraceBuffer* GetTraceBuffer(); |
- // TODO(nduca): switch to per-thread trace buffers to reduce thread |
- // synchronization. |
+ void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event); |
+ void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); |
+ // |flush_count| is used in the following callbacks to check if the callback |
+ // is called for the current flush. |
+ void FlushCurrentThread(int flush_count); |
+ void FinishFlush(int flush_count); |
+ void OnFlushTimeout(int flush_count); |
+ |
// This lock protects TraceLog member accesses from arbitrary threads. |
Lock lock_; |
+ int locked_line_; |
int enable_count_; |
int num_traces_recorded_; |
+ subtle::AtomicWord /* bool */ buffer_is_full_; |
NotificationCallback notification_callback_; |
scoped_ptr<TraceBuffer> logged_events_; |
- EventCallback event_callback_; |
+ subtle::AtomicWord /* EventCallback */ event_callback_; |
bool dispatching_to_observer_list_; |
std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
@@ -566,8 +599,9 @@ class BASE_EXPORT TraceLog { |
base::hash_map<int, std::string> process_labels_; |
int process_sort_index_; |
base::hash_map<int, int> thread_sort_indices_; |
- |
base::hash_map<int, std::string> thread_names_; |
+ |
+ // The following two maps are used only when ECHO_TO_CONSOLE. |
base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
base::hash_map<std::string, int> thread_colors_; |
@@ -579,10 +613,10 @@ class BASE_EXPORT TraceLog { |
TimeDelta time_offset_; |
// Allow tests to wake up when certain events occur. |
- const unsigned char* watch_category_; |
+ subtle::AtomicWord /* const unsigned char* */ watch_category_; |
std::string watch_event_name_; |
- Options trace_options_; |
+ subtle::AtomicWord /* Options */ trace_options_; |
// Sampling thread handles. |
scoped_ptr<TraceSamplingThread> sampling_thread_; |
@@ -590,6 +624,18 @@ class BASE_EXPORT TraceLog { |
CategoryFilter category_filter_; |
+ ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; |
+ |
+ // Contains the message loops of threads that have had at least one event |
+ // added into the local event buffer. Not using MessageLoopProxy because we |
+ // need to know the life time of the message loops. |
+ base::hash_set<MessageLoop*> thread_message_loops_; |
+ |
+ // Set when asynchronous Flush is in progress. |
+ OutputCallback flush_output_callback_; |
+ scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; |
+ int flush_count_; |
+ |
DISALLOW_COPY_AND_ASSIGN(TraceLog); |
}; |