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