@@ -27,19 +27,15 @@ PerformanceTracer::PerformanceTracer()
27
27
: processId_(oscompat::getCurrentProcessId()) {}
28
28
29
29
bool PerformanceTracer::startTracing () {
30
- {
31
- std::lock_guard lock (mutex_);
32
- if (tracing_) {
33
- return false ;
34
- }
35
-
36
- tracing_ = true ;
30
+ if (tracing_.load (std::memory_order_acquire)) {
31
+ return false ;
37
32
}
33
+ tracing_.store (true , std::memory_order_release);
38
34
39
35
reportProcess (processId_, " React Native" );
40
36
41
37
{
42
- std::lock_guard lock (mutex_ );
38
+ std::lock_guard lock (bufferMutex_ );
43
39
buffer_.push_back (TraceEvent{
44
40
.name = " TracingStartedInPage" ,
45
41
.cat = " disabled-by-default-devtools.timeline" ,
@@ -49,42 +45,45 @@ bool PerformanceTracer::startTracing() {
49
45
.tid = oscompat::getCurrentThreadId (),
50
46
.args = folly::dynamic::object (" data" , folly::dynamic::object ()),
51
47
});
52
-
53
- return true ;
54
48
}
49
+
50
+ return true ;
55
51
}
56
52
57
53
bool PerformanceTracer::stopTracing () {
58
- std::lock_guard lock (mutex_);
59
- if (!tracing_) {
54
+ if (!tracing_.load (std::memory_order_acquire)) {
60
55
return false ;
61
56
}
57
+ tracing_.store (false , std::memory_order_release);
62
58
63
- // This is synthetic Trace Event, which should not be represented on a
64
- // timeline. CDT is not using Profile or ProfileChunk events for determining
65
- // trace timeline window, this is why trace that only contains JavaScript
66
- // samples will be displayed as empty. We use this event to avoid that.
67
- // This could happen for non-bridgeless apps, where Performance interface is
68
- // not supported and no spec-compliant Event Loop implementation.
69
- buffer_.push_back (TraceEvent{
70
- .name = " ReactNative-TracingStopped" ,
71
- .cat = " disabled-by-default-devtools.timeline" ,
72
- .ph = ' I' ,
73
- .ts = HighResTimeStamp::now (),
74
- .pid = processId_,
75
- .tid = oscompat::getCurrentThreadId (),
76
- });
59
+ {
60
+ std::lock_guard lock (bufferMutex_);
61
+ // This is synthetic Trace Event, which should not be represented on a
62
+ // timeline. CDT is not using Profile or ProfileChunk events for determining
63
+ // trace timeline window, this is why trace that only contains JavaScript
64
+ // samples will be displayed as empty. We use this event to avoid that.
65
+ // This could happen for non-bridgeless apps, where Performance interface is
66
+ // not supported and no spec-compliant Event Loop implementation.
67
+ buffer_.push_back (TraceEvent{
68
+ .name = " ReactNative-TracingStopped" ,
69
+ .cat = " disabled-by-default-devtools.timeline" ,
70
+ .ph = ' I' ,
71
+ .ts = HighResTimeStamp::now (),
72
+ .pid = processId_,
73
+ .tid = oscompat::getCurrentThreadId (),
74
+ });
75
+ }
77
76
78
- performanceMeasureCount_ = 0 ;
79
- tracing_ = false ;
77
+ // Potential increments of this counter are covered by tracing_ atomic flag.
78
+ performanceMeasureCount_. store ( 0 , std::memory_order_relaxed) ;
80
79
return true ;
81
80
}
82
81
83
82
void PerformanceTracer::collectEvents (
84
83
const std::function<void (const folly::dynamic& eventsChunk)>&
85
84
resultCallback,
86
85
uint16_t chunkSize) {
87
- std::lock_guard lock (mutex_ );
86
+ std::lock_guard lock (bufferMutex_ );
88
87
89
88
if (buffer_.empty ()) {
90
89
return ;
@@ -110,15 +109,11 @@ void PerformanceTracer::collectEvents(
110
109
void PerformanceTracer::reportMark (
111
110
const std::string_view& name,
112
111
HighResTimeStamp start) {
113
- if (!tracing_) {
114
- return ;
115
- }
116
-
117
- std::lock_guard<std::mutex> lock (mutex_);
118
- if (!tracing_) {
112
+ if (!isTracing ()) {
119
113
return ;
120
114
}
121
115
116
+ std::lock_guard<std::mutex> lock (bufferMutex_);
122
117
buffer_.push_back (TraceEvent{
123
118
.name = std::string (name),
124
119
.cat = " blink.user_timing" ,
@@ -134,12 +129,7 @@ void PerformanceTracer::reportMeasure(
134
129
HighResTimeStamp start,
135
130
HighResDuration duration,
136
131
const std::optional<DevToolsTrackEntryPayload>& trackMetadata) {
137
- if (!tracing_) {
138
- return ;
139
- }
140
-
141
- std::lock_guard<std::mutex> lock (mutex_);
142
- if (!tracing_) {
132
+ if (!isTracing ()) {
143
133
return ;
144
134
}
145
135
@@ -152,10 +142,13 @@ void PerformanceTracer::reportMeasure(
152
142
folly::dynamic::object (" detail" , folly::toJson (devtoolsObject));
153
143
}
154
144
155
- ++performanceMeasureCount_;
145
+ auto eventId =
146
+ performanceMeasureCount_.fetch_add (1 , std::memory_order_relaxed);
156
147
auto currentThreadId = oscompat::getCurrentThreadId ();
148
+
149
+ std::lock_guard<std::mutex> lock (bufferMutex_);
157
150
buffer_.push_back (TraceEvent{
158
- .id = performanceMeasureCount_ ,
151
+ .id = eventId ,
159
152
.name = std::string (name),
160
153
.cat = " blink.user_timing" ,
161
154
.ph = ' b' ,
@@ -165,7 +158,7 @@ void PerformanceTracer::reportMeasure(
165
158
.args = beginEventArgs,
166
159
});
167
160
buffer_.push_back (TraceEvent{
168
- .id = performanceMeasureCount_ ,
161
+ .id = eventId ,
169
162
.name = std::string (name),
170
163
.cat = " blink.user_timing" ,
171
164
.ph = ' e' ,
@@ -176,15 +169,11 @@ void PerformanceTracer::reportMeasure(
176
169
}
177
170
178
171
void PerformanceTracer::reportProcess (uint64_t id, const std::string& name) {
179
- if (!tracing_) {
180
- return ;
181
- }
182
-
183
- std::lock_guard<std::mutex> lock (mutex_);
184
- if (!tracing_) {
172
+ if (!isTracing ()) {
185
173
return ;
186
174
}
187
175
176
+ std::lock_guard<std::mutex> lock (bufferMutex_);
188
177
buffer_.push_back (TraceEvent{
189
178
.name = " process_name" ,
190
179
.cat = " __metadata" ,
@@ -201,15 +190,11 @@ void PerformanceTracer::reportJavaScriptThread() {
201
190
}
202
191
203
192
void PerformanceTracer::reportThread (uint64_t id, const std::string& name) {
204
- if (!tracing_) {
205
- return ;
206
- }
207
-
208
- std::lock_guard<std::mutex> lock (mutex_);
209
- if (!tracing_) {
193
+ if (!isTracing ()) {
210
194
return ;
211
195
}
212
196
197
+ std::lock_guard<std::mutex> lock (bufferMutex_);
213
198
buffer_.push_back (TraceEvent{
214
199
.name = " thread_name" ,
215
200
.cat = " __metadata" ,
@@ -238,15 +223,11 @@ void PerformanceTracer::reportThread(uint64_t id, const std::string& name) {
238
223
void PerformanceTracer::reportEventLoopTask (
239
224
HighResTimeStamp start,
240
225
HighResTimeStamp end) {
241
- if (!tracing_) {
242
- return ;
243
- }
244
-
245
- std::lock_guard lock (mutex_);
246
- if (!tracing_) {
226
+ if (!isTracing ()) {
247
227
return ;
248
228
}
249
229
230
+ std::lock_guard lock (bufferMutex_);
250
231
buffer_.push_back (TraceEvent{
251
232
.name = " RunTask" ,
252
233
.cat = " disabled-by-default-devtools.timeline" ,
@@ -261,15 +242,11 @@ void PerformanceTracer::reportEventLoopTask(
261
242
void PerformanceTracer::reportEventLoopMicrotasks (
262
243
HighResTimeStamp start,
263
244
HighResTimeStamp end) {
264
- if (!tracing_) {
265
- return ;
266
- }
267
-
268
- std::lock_guard lock (mutex_);
269
- if (!tracing_) {
245
+ if (!isTracing ()) {
270
246
return ;
271
247
}
272
248
249
+ std::lock_guard lock (bufferMutex_);
273
250
buffer_.push_back (TraceEvent{
274
251
.name = " RunMicrotasks" ,
275
252
.cat = " v8.execute" ,
0 commit comments