Skip to content

Commit

Permalink
Add ReanimatedSystraceSection (#6376)
Browse files Browse the repository at this point in the history
## 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 <40713406+tjzel@users.noreply.github.com>
  • Loading branch information
bartlomiejbloniarz and tjzel authored Jan 8, 2025
1 parent 2c18d91 commit 6586c5f
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <reanimated/RuntimeDecorators/UIRuntimeDecorator.h>
#include <reanimated/Tools/CollectionUtils.h>
#include <reanimated/Tools/FeaturesConfig.h>
#include <reanimated/Tools/ReanimatedSystraceSection.h>
#include <unordered_map>

#ifdef RCT_NEW_ARCH_ENABLED
Expand Down Expand Up @@ -588,6 +589,8 @@ void ReanimatedModuleProxy::performOperations() {
return;
}

ReanimatedSystraceSection s("performOperations");

auto copiedOperationsQueue = std::move(operationsInBatch_);
operationsInBatch_.clear();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#pragma once
#include <string>
#include <vector>

#ifdef REANIMATED_PROFILING

#if defined(__APPLE__)
#include <os/trace_base.h>

#if OS_LOG_TARGET_HAS_10_15_FEATURES
#include <os/log.h>
#include <os/signpost.h>
#include <sstream>
#endif // OS_LOG_TARGET_HAS_10_15_FEATURES

#elif defined(ANDROID)

#include <android/trace.h>

#endif // defined(ANDROID)

#endif // REANIMATED_PROFILING

namespace reanimated {

#if defined(ANDROID) && defined(REANIMATED_PROFILING)

struct ReanimatedSystraceSection {
public:
template <typename... ConvertsToStringPiece>
explicit ReanimatedSystraceSection(
const char *name,
ConvertsToStringPiece &&...args) {
ATrace_beginSection(name);
}

~ReanimatedSystraceSection() {
ATrace_endSection();
}
};

// The apple part is copied from React Native
// from
// https://github.com/facebook/react-native/blob/5697d923a05119314b4cfcd556cb243986637764/packages/react-native/ReactCommon/cxxreact/SystraceSection.h
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && \
defined(REANIMATED_PROFILING)

template <typename T, typename = void>
struct renderer {
static std::string render(const T &t) {
std::ostringstream oss;
oss << t;
return oss.str();
}
};

template <typename T>
static auto render(const T &t)
-> decltype(renderer<T>::render(std::declval<const T &>())) {
return renderer<T>::render(t);
}

inline os_log_t instrumentsLogHandle = nullptr;

static inline os_log_t getOrCreateInstrumentsLogHandle() {
if (!instrumentsLogHandle) {
instrumentsLogHandle = os_log_create(
"dev.reanimated.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
}
return instrumentsLogHandle;
}

struct ReanimatedSystraceSection {
public:
template <typename... ConvertsToStringPiece>
explicit ReanimatedSystraceSection(
const char *name,
ConvertsToStringPiece &&...args) {
os_log_t instrumentsLogHandle =
reanimated::getOrCreateInstrumentsLogHandle();

// If the log isn't enabled, we don't want the performance overhead of the
// rest of the code below.
if (!os_signpost_enabled(instrumentsLogHandle)) {
return;
}

name_ = name;

const auto argsVector =
std::vector<std::string>{reanimated::render(args)...};
std::string argsString = "";
for (size_t i = 0; i < argsVector.size(); i += 2) {
argsString += argsVector[i] + "=" + argsVector[i + 1] + ";";
}

signpostID_ = os_signpost_id_make_with_pointer(instrumentsLogHandle, this);

os_signpost_interval_begin(
instrumentsLogHandle,
signpostID_,
"Reanimated",
"%s begin: %s",
name,
argsString.c_str());
}

~ReanimatedSystraceSection() {
os_signpost_interval_end(
reanimated::instrumentsLogHandle,
signpostID_,
"Reanimated",
"%s end",
name_.data());
}

private:
os_signpost_id_t signpostID_ = OS_SIGNPOST_ID_INVALID;
std::string_view name_;
};

#else

struct ReanimatedSystraceSection {
public:
template <typename... ConvertsToStringPiece>
explicit ReanimatedSystraceSection(
const char *name,
ConvertsToStringPiece &&...args) {}
};

#endif // defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES &&
// defined(REANIMATED_PROFILING)

} // namespace reanimated
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endif()

set_target_properties(reanimated PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(reanimated worklets)
target_link_libraries(reanimated worklets android)

if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
target_link_libraries(reanimated ReactAndroid::reactnative)
Expand Down

0 comments on commit 6586c5f

Please sign in to comment.