1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
base / trace_event / trace_event_impl.h [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
#ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
#define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
#include <stdint.h>
#include <memory>
#include <string>
#include "base/base_export.h"
#include "base/compiler_specific.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/process/process_handle.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/trace_arguments.h"
#include "build/build_config.h"
namespace base {
namespace trace_event {
typedef base::RepeatingCallback<bool(const char* arg_name)>
ArgumentNameFilterPredicate;
typedef base::RepeatingCallback<bool(const char* category_group_name,
const char* event_name,
ArgumentNameFilterPredicate*)>
ArgumentFilterPredicate;
typedef base::RepeatingCallback<bool(const std::string& metadata_name)>
MetadataFilterPredicate;
struct TraceEventHandle {
uint32_t chunk_seq;
// These numbers of bits must be kept consistent with
// TraceBufferChunk::kMaxTrunkIndex and
// TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
unsigned chunk_index : 26;
unsigned event_index : 6;
};
class BASE_EXPORT TraceEvent {
public:
// TODO(crbug.com/40599662): Remove once all users have been updated.
using TraceValue = base::trace_event::TraceValue;
TraceEvent();
TraceEvent(PlatformThreadId thread_id,
TimeTicks timestamp,
ThreadTicks thread_timestamp,
char phase,
const unsigned char* category_group_enabled,
const char* name,
const char* scope,
unsigned long long id,
TraceArguments* args,
unsigned int flags);
TraceEvent(const TraceEvent&) = delete;
TraceEvent& operator=(const TraceEvent&) = delete;
~TraceEvent();
// Allow move operations.
TraceEvent(TraceEvent&&) noexcept;
TraceEvent& operator=(TraceEvent&&) noexcept;
// Reset instance to empty state.
void Reset();
// Reset instance to new state. This is equivalent but slightly more
// efficient than doing a move assignment, since it avoids creating
// temporary copies. I.e. compare these two statements:
//
// event = TraceEvent(thread_id, ....); // Create and destroy temporary.
// event.Reset(thread_id, ...); // Direct re-initialization.
//
void Reset(PlatformThreadId thread_id,
TimeTicks timestamp,
ThreadTicks thread_timestamp,
char phase,
const unsigned char* category_group_enabled,
const char* name,
const char* scope,
unsigned long long id,
TraceArguments* args,
unsigned int flags);
void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
// Serialize event data to JSON
void AppendAsJSON(
std::string* out,
const ArgumentFilterPredicate& argument_filter_predicate) const;
void AppendPrettyPrinted(std::ostringstream* out) const;
TimeTicks timestamp() const { return timestamp_; }
ThreadTicks thread_timestamp() const { return thread_timestamp_; }
char phase() const { return phase_; }
PlatformThreadId thread_id() const { return thread_id_; }
ProcessId process_id() const { return process_id_; }
TimeDelta duration() const { return duration_; }
TimeDelta thread_duration() const { return thread_duration_; }
const char* scope() const { return scope_; }
unsigned long long id() const { return id_; }
unsigned int flags() const { return flags_; }
// Exposed for unittesting:
const StringStorage& parameter_copy_storage() const LIFETIME_BOUND {
return parameter_copy_storage_;
}
const unsigned char* category_group_enabled() const {
return category_group_enabled_;
}
const char* name() const { return name_; }
size_t arg_size() const { return args_.size(); }
unsigned char arg_type(size_t index) const { return args_.types()[index]; }
const char* arg_name(size_t index) const { return args_.names()[index]; }
const TraceValue& arg_value(size_t index) const {
return args_.values()[index];
}
ConvertableToTraceFormat* arg_convertible_value(size_t index) {
return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE)
? arg_value(index).as_convertable
: nullptr;
}
private:
void InitArgs(TraceArguments* args);
// Note: these are ordered by size (largest first) for optimal packing.
TimeTicks timestamp_ = TimeTicks();
ThreadTicks thread_timestamp_ = ThreadTicks();
TimeDelta duration_ = TimeDelta::FromInternalValue(-1);
TimeDelta thread_duration_ = TimeDelta();
// scope_ and id_ can be used to store phase-specific data.
// The following should be default-initialized to the expression
// trace_event_internal::kGlobalScope, which is nullptr, but its definition
// cannot be included here due to cyclical header dependencies.
// The equivalence is checked with a static_assert() in trace_event_impl.cc.
const char* scope_ = nullptr;
unsigned long long id_ = 0u;
raw_ptr<const unsigned char> category_group_enabled_ = nullptr;
const char* name_ = nullptr;
StringStorage parameter_copy_storage_;
TraceArguments args_;
// Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
// tid: thread_id_, pid: current_process_id (default case).
// tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
union {
PlatformThreadId thread_id_ = 0;
ProcessId process_id_;
};
unsigned int flags_ = 0;
char phase_ = TRACE_EVENT_PHASE_BEGIN;
};
} // namespace trace_event
} // namespace base
#endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_