Skip to content

Commit 6586c5f

Browse files
Add ReanimatedSystraceSection (#6376)
## Summary This PR adds `ReanimatedSystraceSection` class that allow for easy marking of relevant code sections on Android (through ATrace) and iOS (through signposts). When `REANIMATED_PROFILING` is not defined the profiling code will compile to `no-op`, meaning we can have these systrace sections in our code permanently. ## Test plan --------- Co-authored-by: Tomasz Żelawski <[email protected]>
1 parent 2c18d91 commit 6586c5f

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <reanimated/RuntimeDecorators/UIRuntimeDecorator.h>
33
#include <reanimated/Tools/CollectionUtils.h>
44
#include <reanimated/Tools/FeaturesConfig.h>
5+
#include <reanimated/Tools/ReanimatedSystraceSection.h>
56
#include <unordered_map>
67

78
#ifdef RCT_NEW_ARCH_ENABLED
@@ -588,6 +589,8 @@ void ReanimatedModuleProxy::performOperations() {
588589
return;
589590
}
590591

592+
ReanimatedSystraceSection s("performOperations");
593+
591594
auto copiedOperationsQueue = std::move(operationsInBatch_);
592595
operationsInBatch_.clear();
593596

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#pragma once
2+
#include <string>
3+
#include <vector>
4+
5+
#ifdef REANIMATED_PROFILING
6+
7+
#if defined(__APPLE__)
8+
#include <os/trace_base.h>
9+
10+
#if OS_LOG_TARGET_HAS_10_15_FEATURES
11+
#include <os/log.h>
12+
#include <os/signpost.h>
13+
#include <sstream>
14+
#endif // OS_LOG_TARGET_HAS_10_15_FEATURES
15+
16+
#elif defined(ANDROID)
17+
18+
#include <android/trace.h>
19+
20+
#endif // defined(ANDROID)
21+
22+
#endif // REANIMATED_PROFILING
23+
24+
namespace reanimated {
25+
26+
#if defined(ANDROID) && defined(REANIMATED_PROFILING)
27+
28+
struct ReanimatedSystraceSection {
29+
public:
30+
template <typename... ConvertsToStringPiece>
31+
explicit ReanimatedSystraceSection(
32+
const char *name,
33+
ConvertsToStringPiece &&...args) {
34+
ATrace_beginSection(name);
35+
}
36+
37+
~ReanimatedSystraceSection() {
38+
ATrace_endSection();
39+
}
40+
};
41+
42+
// The apple part is copied from React Native
43+
// from
44+
// https://github.com/facebook/react-native/blob/5697d923a05119314b4cfcd556cb243986637764/packages/react-native/ReactCommon/cxxreact/SystraceSection.h
45+
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && \
46+
defined(REANIMATED_PROFILING)
47+
48+
template <typename T, typename = void>
49+
struct renderer {
50+
static std::string render(const T &t) {
51+
std::ostringstream oss;
52+
oss << t;
53+
return oss.str();
54+
}
55+
};
56+
57+
template <typename T>
58+
static auto render(const T &t)
59+
-> decltype(renderer<T>::render(std::declval<const T &>())) {
60+
return renderer<T>::render(t);
61+
}
62+
63+
inline os_log_t instrumentsLogHandle = nullptr;
64+
65+
static inline os_log_t getOrCreateInstrumentsLogHandle() {
66+
if (!instrumentsLogHandle) {
67+
instrumentsLogHandle = os_log_create(
68+
"dev.reanimated.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
69+
}
70+
return instrumentsLogHandle;
71+
}
72+
73+
struct ReanimatedSystraceSection {
74+
public:
75+
template <typename... ConvertsToStringPiece>
76+
explicit ReanimatedSystraceSection(
77+
const char *name,
78+
ConvertsToStringPiece &&...args) {
79+
os_log_t instrumentsLogHandle =
80+
reanimated::getOrCreateInstrumentsLogHandle();
81+
82+
// If the log isn't enabled, we don't want the performance overhead of the
83+
// rest of the code below.
84+
if (!os_signpost_enabled(instrumentsLogHandle)) {
85+
return;
86+
}
87+
88+
name_ = name;
89+
90+
const auto argsVector =
91+
std::vector<std::string>{reanimated::render(args)...};
92+
std::string argsString = "";
93+
for (size_t i = 0; i < argsVector.size(); i += 2) {
94+
argsString += argsVector[i] + "=" + argsVector[i + 1] + ";";
95+
}
96+
97+
signpostID_ = os_signpost_id_make_with_pointer(instrumentsLogHandle, this);
98+
99+
os_signpost_interval_begin(
100+
instrumentsLogHandle,
101+
signpostID_,
102+
"Reanimated",
103+
"%s begin: %s",
104+
name,
105+
argsString.c_str());
106+
}
107+
108+
~ReanimatedSystraceSection() {
109+
os_signpost_interval_end(
110+
reanimated::instrumentsLogHandle,
111+
signpostID_,
112+
"Reanimated",
113+
"%s end",
114+
name_.data());
115+
}
116+
117+
private:
118+
os_signpost_id_t signpostID_ = OS_SIGNPOST_ID_INVALID;
119+
std::string_view name_;
120+
};
121+
122+
#else
123+
124+
struct ReanimatedSystraceSection {
125+
public:
126+
template <typename... ConvertsToStringPiece>
127+
explicit ReanimatedSystraceSection(
128+
const char *name,
129+
ConvertsToStringPiece &&...args) {}
130+
};
131+
132+
#endif // defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES &&
133+
// defined(REANIMATED_PROFILING)
134+
135+
} // namespace reanimated

packages/react-native-reanimated/android/src/main/cpp/reanimated/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ endif()
2929

3030
set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX)
3131

32-
target_link_libraries(reanimated worklets)
32+
target_link_libraries(reanimated worklets android)
3333

3434
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
3535
target_link_libraries(reanimated ReactAndroid::reactnative)

0 commit comments

Comments
 (0)