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 <string>
13 #include <vector>
14 
15 #include "base/atomicops.h"
16 #include "base/base_export.h"
17 #include "base/callback.h"
18 #include "base/macros.h"
19 #include "base/observer_list.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/strings/string_util.h"
22 #include "base/synchronization/condition_variable.h"
23 #include "base/synchronization/lock.h"
24 #include "base/threading/thread_local.h"
25 #include "base/trace_event/common/trace_event_common.h"
26 #include "base/trace_event/thread_instruction_count.h"
27 #include "base/trace_event/trace_arguments.h"
28 #include "base/trace_event/trace_event_memory_overhead.h"
29 #include "build/build_config.h"
30 
31 namespace base {
32 namespace trace_event {
33 
34 typedef base::RepeatingCallback<bool(const char* arg_name)>
35     ArgumentNameFilterPredicate;
36 
37 typedef base::RepeatingCallback<bool(const char* category_group_name,
38                                      const char* event_name,
39                                      ArgumentNameFilterPredicate*)>
40     ArgumentFilterPredicate;
41 
42 typedef base::RepeatingCallback<bool(const std::string& metadata_name)>
43     MetadataFilterPredicate;
44 
45 struct TraceEventHandle {
46   uint32_t chunk_seq;
47   // These numbers of bits must be kept consistent with
48   // TraceBufferChunk::kMaxTrunkIndex and
49   // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
50   unsigned chunk_index : 26;
51   unsigned event_index : 6;
52 };
53 
54 class BASE_EXPORT TraceEvent {
55  public:
56   // TODO(898794): Remove once all users have been updated.
57   using TraceValue = base::trace_event::TraceValue;
58 
59   TraceEvent();
60 
61   TraceEvent(int thread_id,
62              TimeTicks timestamp,
63              ThreadTicks thread_timestamp,
64              ThreadInstructionCount thread_instruction_count,
65              char phase,
66              const unsigned char* category_group_enabled,
67              const char* name,
68              const char* scope,
69              unsigned long long id,
70              unsigned long long bind_id,
71              TraceArguments* args,
72              unsigned int flags);
73 
74   ~TraceEvent();
75 
76   // Allow move operations.
77   TraceEvent(TraceEvent&&) noexcept;
78   TraceEvent& operator=(TraceEvent&&) noexcept;
79 
80   // Reset instance to empty state.
81   void Reset();
82 
83   // Reset instance to new state. This is equivalent but slightly more
84   // efficient than doing a move assignment, since it avoids creating
85   // temporary copies. I.e. compare these two statements:
86   //
87   //    event = TraceEvent(thread_id, ....);  // Create and destroy temporary.
88   //    event.Reset(thread_id, ...);  // Direct re-initialization.
89   //
90   void Reset(int thread_id,
91              TimeTicks timestamp,
92              ThreadTicks thread_timestamp,
93              ThreadInstructionCount thread_instruction_count,
94              char phase,
95              const unsigned char* category_group_enabled,
96              const char* name,
97              const char* scope,
98              unsigned long long id,
99              unsigned long long bind_id,
100              TraceArguments* args,
101              unsigned int flags);
102 
103   void UpdateDuration(const TimeTicks& now,
104                       const ThreadTicks& thread_now,
105                       ThreadInstructionCount thread_instruction_now);
106 
107   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
108 
109   // Serialize event data to JSON
110   void AppendAsJSON(
111       std::string* out,
112       const ArgumentFilterPredicate& argument_filter_predicate) const;
113   void AppendPrettyPrinted(std::ostringstream* out) const;
114 
timestamp()115   TimeTicks timestamp() const { return timestamp_; }
thread_timestamp()116   ThreadTicks thread_timestamp() const { return thread_timestamp_; }
thread_instruction_count()117   ThreadInstructionCount thread_instruction_count() const {
118     return thread_instruction_count_;
119   }
phase()120   char phase() const { return phase_; }
thread_id()121   int thread_id() const { return thread_id_; }
process_id()122   int process_id() const { return process_id_; }
duration()123   TimeDelta duration() const { return duration_; }
thread_duration()124   TimeDelta thread_duration() const { return thread_duration_; }
thread_instruction_delta()125   ThreadInstructionDelta thread_instruction_delta() const {
126     return thread_instruction_delta_;
127   }
scope()128   const char* scope() const { return scope_; }
id()129   unsigned long long id() const { return id_; }
flags()130   unsigned int flags() const { return flags_; }
bind_id()131   unsigned long long bind_id() const { return bind_id_; }
132   // Exposed for unittesting:
133 
parameter_copy_storage()134   const StringStorage& parameter_copy_storage() const {
135     return parameter_copy_storage_;
136   }
137 
category_group_enabled()138   const unsigned char* category_group_enabled() const {
139     return category_group_enabled_;
140   }
141 
name()142   const char* name() const { return name_; }
143 
arg_size()144   size_t arg_size() const { return args_.size(); }
arg_type(size_t index)145   unsigned char arg_type(size_t index) const { return args_.types()[index]; }
arg_name(size_t index)146   const char* arg_name(size_t index) const { return args_.names()[index]; }
arg_value(size_t index)147   const TraceValue& arg_value(size_t index) const {
148     return args_.values()[index];
149   }
150 
arg_convertible_value(size_t index)151   ConvertableToTraceFormat* arg_convertible_value(size_t index) {
152     return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE)
153                ? arg_value(index).as_convertable
154                : nullptr;
155   }
156 
157 #if defined(OS_ANDROID)
158   void SendToATrace();
159 #endif
160 
161  private:
162   void InitArgs(TraceArguments* args);
163 
164   // Note: these are ordered by size (largest first) for optimal packing.
165   TimeTicks timestamp_ = TimeTicks();
166   ThreadTicks thread_timestamp_ = ThreadTicks();
167   TimeDelta duration_ = TimeDelta::FromInternalValue(-1);
168   TimeDelta thread_duration_ = TimeDelta();
169   ThreadInstructionCount thread_instruction_count_ = ThreadInstructionCount();
170   ThreadInstructionDelta thread_instruction_delta_ = ThreadInstructionDelta();
171   // scope_ and id_ can be used to store phase-specific data.
172   // The following should be default-initialized to the expression
173   // trace_event_internal::kGlobalScope, which is nullptr, but its definition
174   // cannot be included here due to cyclical header dependencies.
175   // The equivalence is checked with a static_assert() in trace_event_impl.cc.
176   const char* scope_ = nullptr;
177   unsigned long long id_ = 0u;
178   const unsigned char* category_group_enabled_ = nullptr;
179   const char* name_ = nullptr;
180   StringStorage parameter_copy_storage_;
181   TraceArguments args_;
182   // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
183   //  tid: thread_id_, pid: current_process_id (default case).
184   //  tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
185   union {
186     int thread_id_ = 0;
187     int process_id_;
188   };
189   unsigned int flags_ = 0;
190   unsigned long long bind_id_ = 0;
191   char phase_ = TRACE_EVENT_PHASE_BEGIN;
192 
193   DISALLOW_COPY_AND_ASSIGN(TraceEvent);
194 };
195 
196 }  // namespace trace_event
197 }  // namespace base
198 
199 #endif  // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
200