Skip to content

Commit a8a76f9

Browse files
rubennortefacebook-github-bot
authored andcommitted
Improve profiling information for timers (facebook#45091)
Summary: Pull Request resolved: facebook#45091 Changelog: [internal] We're currently logging when we execute timers in Systrace/Perfetto, but we have no information about them whatsoever. This adds some additional information: * What kind of timer it is * It's ID * And most importantly, when it was created (including the ID as well). This allows us to know where was a specific timer scheduled and with what API. Reviewed By: bgirard Differential Revision: D58832112 fbshipit-source-id: 1bc11759b6c8296acf63ff3533ca1dc3428360a7
1 parent fdf0183 commit a8a76f9

File tree

2 files changed

+83
-14
lines changed

2 files changed

+83
-14
lines changed

packages/react-native/ReactCommon/react/runtime/TimerManager.cpp

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@
1313

1414
namespace facebook::react {
1515

16+
namespace {
17+
inline const char* getTimerSourceName(TimerSource source) {
18+
switch (source) {
19+
case TimerSource::Unknown:
20+
return "unknown";
21+
case TimerSource::SetTimeout:
22+
return "setTimeout";
23+
case TimerSource::SetInterval:
24+
return "setInterval";
25+
case TimerSource::RequestAnimationFrame:
26+
return "requestAnimationFrame";
27+
}
28+
}
29+
} // namespace
30+
1631
TimerManager::TimerManager(
1732
std::unique_ptr<PlatformTimerRegistry> platformTimerRegistry) noexcept
1833
: platformTimerRegistry_(std::move(platformTimerRegistry)) {}
@@ -60,14 +75,28 @@ void TimerManager::callReactNativeMicrotasks(jsi::Runtime& runtime) {
6075
TimerHandle TimerManager::createTimer(
6176
jsi::Function&& callback,
6277
std::vector<jsi::Value>&& args,
63-
double delay) {
78+
double delay,
79+
TimerSource source) {
6480
// Get the id for the callback.
6581
TimerHandle timerID = timerIndex_++;
82+
83+
SystraceSection s(
84+
"TimerManager::createTimer",
85+
"id",
86+
timerID,
87+
"type",
88+
getTimerSourceName(source),
89+
"delay",
90+
delay);
91+
6692
timers_.emplace(
6793
std::piecewise_construct,
6894
std::forward_as_tuple(timerID),
6995
std::forward_as_tuple(
70-
std::move(callback), std::move(args), /* repeat */ false));
96+
std::move(callback),
97+
std::move(args),
98+
/* repeat */ false,
99+
source));
71100

72101
platformTimerRegistry_->createTimer(timerID, delay);
73102

@@ -77,14 +106,25 @@ TimerHandle TimerManager::createTimer(
77106
TimerHandle TimerManager::createRecurringTimer(
78107
jsi::Function&& callback,
79108
std::vector<jsi::Value>&& args,
80-
double delay) {
109+
double delay,
110+
TimerSource source) {
81111
// Get the id for the callback.
82112
TimerHandle timerID = timerIndex_++;
113+
114+
SystraceSection s(
115+
"TimerManager::createRecurringTimer",
116+
"id",
117+
timerID,
118+
"type",
119+
getTimerSourceName(source),
120+
"delay",
121+
delay);
122+
83123
timers_.emplace(
84124
std::piecewise_construct,
85125
std::forward_as_tuple(timerID),
86126
std::forward_as_tuple(
87-
std::move(callback), std::move(args), /* repeat */ true));
127+
std::move(callback), std::move(args), /* repeat */ true, source));
88128

89129
platformTimerRegistry_->createRecurringTimer(timerID, delay);
90130

@@ -131,11 +171,20 @@ void TimerManager::deleteRecurringTimer(
131171

132172
void TimerManager::callTimer(TimerHandle timerHandle) {
133173
runtimeExecutor_([this, timerHandle](jsi::Runtime& runtime) {
134-
SystraceSection s("TimerManager::callTimer");
135174
auto it = timers_.find(timerHandle);
136175
if (it != timers_.end()) {
137-
bool repeats = it->second.repeat;
138-
it->second.invoke(runtime);
176+
auto& timerCallback = it->second;
177+
bool repeats = timerCallback.repeat;
178+
179+
{
180+
SystraceSection s(
181+
"TimerManager::callTimer",
182+
"id",
183+
timerHandle,
184+
"type",
185+
getTimerSourceName(timerCallback.source));
186+
timerCallback.invoke(runtime);
187+
}
139188

140189
if (!repeats) {
141190
// Invoking a timer has the potential to delete it. Do not re-use the
@@ -246,7 +295,11 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
246295
moreArgs.emplace_back(rt, args[extraArgNum]);
247296
}
248297

249-
return createTimer(std::move(callback), std::move(moreArgs), delay);
298+
return createTimer(
299+
std::move(callback),
300+
std::move(moreArgs),
301+
delay,
302+
TimerSource::SetTimeout);
250303
}));
251304

252305
runtime.global().setProperty(
@@ -301,7 +354,10 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
301354
}
302355

303356
return createRecurringTimer(
304-
std::move(callback), std::move(moreArgs), delay);
357+
std::move(callback),
358+
std::move(moreArgs),
359+
delay,
360+
TimerSource::SetInterval);
305361
}));
306362

307363
runtime.global().setProperty(
@@ -370,7 +426,8 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) {
370426
return createTimer(
371427
std::move(callback),
372428
std::vector<jsi::Value>(),
373-
/* delay */ 0);
429+
/* delay */ 0,
430+
TimerSource::RequestAnimationFrame);
374431
}));
375432

376433
runtime.global().setProperty(

packages/react-native/ReactCommon/react/runtime/TimerManager.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,26 @@ namespace facebook::react {
1818

1919
using TimerHandle = int;
2020

21+
enum class TimerSource {
22+
Unknown,
23+
SetTimeout,
24+
SetInterval,
25+
RequestAnimationFrame
26+
};
27+
2128
/*
2229
* Wraps a jsi::Function to make it copyable so we can pass it into a lambda.
2330
*/
2431
struct TimerCallback {
2532
TimerCallback(
2633
jsi::Function callback,
2734
std::vector<jsi::Value> args,
28-
bool repeat)
35+
bool repeat,
36+
TimerSource source = TimerSource::Unknown)
2937
: callback_(std::move(callback)),
3038
args_(std::move(args)),
31-
repeat(repeat) {}
39+
repeat(repeat),
40+
source(source) {}
3241

3342
void invoke(jsi::Runtime& runtime) {
3443
callback_.call(runtime, args_.data(), args_.size());
@@ -37,6 +46,7 @@ struct TimerCallback {
3746
jsi::Function callback_;
3847
const std::vector<jsi::Value> args_;
3948
bool repeat;
49+
TimerSource source;
4050
};
4151

4252
class TimerManager {
@@ -62,14 +72,16 @@ class TimerManager {
6272
TimerHandle createTimer(
6373
jsi::Function&& callback,
6474
std::vector<jsi::Value>&& args,
65-
double delay);
75+
double delay,
76+
TimerSource source = TimerSource::Unknown);
6677

6778
void deleteTimer(jsi::Runtime& runtime, TimerHandle handle);
6879

6980
TimerHandle createRecurringTimer(
7081
jsi::Function&& callback,
7182
std::vector<jsi::Value>&& args,
72-
double delay);
83+
double delay,
84+
TimerSource source = TimerSource::Unknown);
7385

7486
void deleteRecurringTimer(jsi::Runtime& runtime, TimerHandle handle);
7587

0 commit comments

Comments
 (0)