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