diff --git a/packages/react-native/ReactCommon/react/nativemodule/cputime/CPUTime.h b/packages/react-native/ReactCommon/react/nativemodule/cputime/CPUTime.h new file mode 100644 index 00000000000000..fe260ff03f2141 --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/cputime/CPUTime.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#ifdef USE_POSIX_TIME +#include +#else +#include +#endif + +#ifdef USE_POSIX_TIME + +namespace { +const double NANOSECONDS_IN_A_SECOND = 1000000000; +} // namespace + +#endif + +namespace facebook::react { + +#ifdef USE_POSIX_TIME + +inline double getCPUTimeNanos() { + struct timespec time {}; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time); + return static_cast(time.tv_sec) * NANOSECONDS_IN_A_SECOND + + static_cast(time.tv_nsec); +} + +inline bool hasAccurateCPUTimeNanosForBenchmarks() { + return true; +} + +#else + +inline double getCPUTimeNanos() { + auto now = std::chrono::steady_clock::now(); + return static_cast( + std::chrono::duration_cast( + now.time_since_epoch()) + .count()); +} + +inline bool hasAccurateCPUTimeNanosForBenchmarks() { + return false; +} + +#endif + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.cpp b/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.cpp new file mode 100644 index 00000000000000..498a21d09889dc --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "NativeCPUTime.h" + +#include "CPUTime.h" + +#ifdef RN_DISABLE_OSS_PLUGIN_HEADER +#include "Plugins.h" +#endif + +std::shared_ptr NativeCPUTimeModuleProvider( + std::shared_ptr jsInvoker) { + return std::make_shared(std::move(jsInvoker)); +} + +namespace facebook::react { + +NativeCPUTime::NativeCPUTime(std::shared_ptr jsInvoker) + : NativeCPUTimeCxxSpec(std::move(jsInvoker)) {} + +double NativeCPUTime::getCPUTimeNanos(jsi::Runtime& /*runtime*/) { + return facebook::react::getCPUTimeNanos(); +} + +bool NativeCPUTime::hasAccurateCPUTimeNanosForBenchmarks( + jsi::Runtime& /*runtime*/) { + return facebook::react::hasAccurateCPUTimeNanosForBenchmarks(); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.h b/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.h new file mode 100644 index 00000000000000..c6e60b4f66623b --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#if __has_include("rncoreJSI.h") // Cmake headers on Android +#include "rncoreJSI.h" +#elif __has_include("FBReactNativeSpecJSI.h") // CocoaPod headers on Apple +#include "FBReactNativeSpecJSI.h" +#else +#include +#endif + +namespace facebook::react { + +class NativeCPUTime : public NativeCPUTimeCxxSpec { + public: + explicit NativeCPUTime(std::shared_ptr jsInvoker); + + double getCPUTimeNanos(jsi::Runtime& runtime); + bool hasAccurateCPUTimeNanosForBenchmarks(jsi::Runtime& runtime); +}; + +} // namespace facebook::react diff --git a/packages/react-native/src/private/specs/modules/NativeCPUTime.js b/packages/react-native/src/private/specs/modules/NativeCPUTime.js new file mode 100644 index 00000000000000..a2736dc86a083e --- /dev/null +++ b/packages/react-native/src/private/specs/modules/NativeCPUTime.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +import type {TurboModule} from '../../../../Libraries/TurboModule/RCTExport'; + +import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboModuleRegistry'; + +/** + * This is an internal native module meant to be used for performance + * measurements and benchmarks. It is not meant to be used in production. + */ +export interface Spec extends TurboModule { + +getCPUTimeNanos: () => number; + +hasAccurateCPUTimeNanosForBenchmarks: () => boolean; +} + +export default (TurboModuleRegistry.getEnforcing('CPUTimeCxx'): Spec);