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
3 // found in the LICENSE file.
4 
5 
6 #ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
7 #define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
8 
9 #include <stdint.h>
10 
11 #include <stack>
12 #include <string>
13 #include <vector>
14 
15 #include "base/atomicops.h"
16 #include "base/base_export.h"
17 #include "base/callback.h"
18 #include "base/containers/hash_tables.h"
19 #include "base/macros.h"
20 #include "base/memory/ref_counted_memory.h"
21 #include "base/observer_list.h"
22 #include "base/single_thread_task_runner.h"
23 #include "base/strings/string_util.h"
24 #include "base/synchronization/condition_variable.h"
25 #include "base/synchronization/lock.h"
26 #include "base/threading/thread.h"
27 #include "base/threading/thread_local.h"
28 #include "base/trace_event/trace_event_memory_overhead.h"
29 #include "build/build_config.h"
30 
31 namespace base {
32 
33 class WaitableEvent;
34 class MessageLoop;
35 
36 namespace trace_event {
37 
38 typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate;
39 
40 typedef base::Callback<bool(const char* category_group_name,
41                             const char* event_name,
42                             ArgumentNameFilterPredicate*)>
43     ArgumentFilterPredicate;
44 
45 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
46 // class must implement this interface.
47 class BASE_EXPORT ConvertableToTraceFormat
48     : public RefCounted<ConvertableToTraceFormat> {
49  public:
50   // Append the class info to the provided |out| string. The appended
51   // data must be a valid JSON object. Strings must be properly quoted, and
52   // escaped. There is no processing applied to the content after it is
53   // appended.
54   virtual void AppendAsTraceFormat(std::string* out) const = 0;
55 
56   virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
57 
ToString()58   std::string ToString() const {
59     std::string result;
60     AppendAsTraceFormat(&result);
61     return result;
62   }
63 
64  protected:
~ConvertableToTraceFormat()65   virtual ~ConvertableToTraceFormat() {}
66 
67  private:
68   friend class RefCounted<ConvertableToTraceFormat>;
69 };
70 
71 const int kTraceMaxNumArgs = 2;
72 
73 struct TraceEventHandle {
74   uint32_t chunk_seq;
75   // These numbers of bits must be kept consistent with
76   // TraceBufferChunk::kMaxTrunkIndex and
77   // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
78   unsigned chunk_index : 26;
79   unsigned event_index : 6;
80 };
81 
82 class BASE_EXPORT TraceEvent {
83  public:
84   union TraceValue {
85     bool as_bool;
86     unsigned long long as_uint;
87     long long as_int;
88     double as_double;
89     const void* as_pointer;
90     const char* as_string;
91   };
92 
93   TraceEvent();
94   ~TraceEvent();
95 
96   // We don't need to copy TraceEvent except when TraceEventBuffer is cloned.
97   // Use explicit copy method to avoid accidentally misuse of copy.
98   void CopyFrom(const TraceEvent& other);
99 
100   void Initialize(
101       int thread_id,
102       TimeTicks timestamp,
103       ThreadTicks thread_timestamp,
104       char phase,
105       const unsigned char* category_group_enabled,
106       const char* name,
107       unsigned long long id,
108       unsigned long long bind_id,
109       int num_args,
110       const char** arg_names,
111       const unsigned char* arg_types,
112       const unsigned long long* arg_values,
113       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
114       unsigned int flags);
115 
116   void Reset();
117 
118   void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
119 
120   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
121 
122   // Serialize event data to JSON
123   void AppendAsJSON(
124       std::string* out,
125       const ArgumentFilterPredicate& argument_filter_predicate) const;
126   void AppendPrettyPrinted(std::ostringstream* out) const;
127 
128   static void AppendValueAsJSON(unsigned char type,
129                                 TraceValue value,
130                                 std::string* out);
131 
timestamp()132   TimeTicks timestamp() const { return timestamp_; }
thread_timestamp()133   ThreadTicks thread_timestamp() const { return thread_timestamp_; }
phase()134   char phase() const { return phase_; }
thread_id()135   int thread_id() const { return thread_id_; }
duration()136   TimeDelta duration() const { return duration_; }
thread_duration()137   TimeDelta thread_duration() const { return thread_duration_; }
id()138   unsigned long long id() const { return id_; }
flags()139   unsigned int flags() const { return flags_; }
140 
141   // Exposed for unittesting:
142 
parameter_copy_storage()143   const base::RefCountedString* parameter_copy_storage() const {
144     return parameter_copy_storage_.get();
145   }
146 
category_group_enabled()147   const unsigned char* category_group_enabled() const {
148     return category_group_enabled_;
149   }
150 
name()151   const char* name() const { return name_; }
152 
153 #if defined(OS_ANDROID)
154   void SendToATrace();
155 #endif
156 
157  private:
158   // Note: these are ordered by size (largest first) for optimal packing.
159   TimeTicks timestamp_;
160   ThreadTicks thread_timestamp_;
161   TimeDelta duration_;
162   TimeDelta thread_duration_;
163   // id_ can be used to store phase-specific data.
164   unsigned long long id_;
165   TraceValue arg_values_[kTraceMaxNumArgs];
166   const char* arg_names_[kTraceMaxNumArgs];
167   scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
168   const unsigned char* category_group_enabled_;
169   const char* name_;
170   scoped_refptr<base::RefCountedString> parameter_copy_storage_;
171   // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
172   //  tid: thread_id_, pid: current_process_id (default case).
173   //  tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
174   union {
175     int thread_id_;
176     int process_id_;
177   };
178   unsigned int flags_;
179   unsigned long long bind_id_;
180   unsigned char arg_types_[kTraceMaxNumArgs];
181   char phase_;
182 
183   DISALLOW_COPY_AND_ASSIGN(TraceEvent);
184 };
185 
186 }  // namespace trace_event
187 }  // namespace base
188 
189 #endif  // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
190