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
31namespace base {
32
33class WaitableEvent;
34class MessageLoop;
35
36namespace trace_event {
37
38typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate;
39
40typedef 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.
47class 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
58  std::string ToString() const {
59    std::string result;
60    AppendAsTraceFormat(&result);
61    return result;
62  }
63
64 protected:
65  virtual ~ConvertableToTraceFormat() {}
66
67 private:
68  friend class RefCounted<ConvertableToTraceFormat>;
69};
70
71const int kTraceMaxNumArgs = 2;
72
73struct 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
82class 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
132  TimeTicks timestamp() const { return timestamp_; }
133  ThreadTicks thread_timestamp() const { return thread_timestamp_; }
134  char phase() const { return phase_; }
135  int thread_id() const { return thread_id_; }
136  TimeDelta duration() const { return duration_; }
137  TimeDelta thread_duration() const { return thread_duration_; }
138  unsigned long long id() const { return id_; }
139  unsigned int flags() const { return flags_; }
140
141  // Exposed for unittesting:
142
143  const base::RefCountedString* parameter_copy_storage() const {
144    return parameter_copy_storage_.get();
145  }
146
147  const unsigned char* category_group_enabled() const {
148    return category_group_enabled_;
149  }
150
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