// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file is automatically generated by gen_amalgamated. Do not edit.
// gen_amalgamated begin header: include/perfetto/tracing.h
// gen_amalgamated begin header: include/perfetto/base/time.h
// gen_amalgamated begin header: include/perfetto/base/build_config.h
// gen_amalgamated begin header: gen/build_config/perfetto_build_flags.h
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Generated by write_buildflag_header.py
// fix_include_guards: off
#ifndef GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
#define GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
// clang-format off
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ENABLE_ETM_IMPORTER() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_ON() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_OFF() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERBOSE_LOGS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_HTTPD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_INSTRUMENTS() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_SYSTEM_CONSUMER() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_THREAD_SAFETY_ANNOTATIONS() (0)
// clang-format on
#endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
#define INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
// Allows to define build flags that give a compiler error if the header that
// defined the flag is not included, instead of silently ignoring the #if block.
#define PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b) a
##b
#define PERFETTO_BUILDFLAG_CAT(a, b) PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b)
#define PERFETTO_BUILDFLAG(flag) \
(PERFETTO_BUILDFLAG_CAT(PERFETTO_BUILDFLAG_DEFINE_, flag)())
#if defined(__ANDROID__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#elif defined(__APPLE__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
// Include TARGET_OS_IPHONE when on __APPLE__ systems.
#include <TargetConditionals.h>
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#endif
#elif defined(__linux__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#elif defined(__QNXNTO__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 1
#elif defined(_WIN32)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#elif defined(__EMSCRIPTEN__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#elif defined(__Fuchsia__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#elif defined(__native_client__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX_BUT_NOT_QNX() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_QNX() 0
#else
#error OS
not supported (see build_config.h)
#endif
#if defined(__clang__)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
#elif defined(__GNUC__)
// Careful: Clang also defines this!
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 1
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
#elif defined(_MSC_VER)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
#endif
#if defined(PERFETTO_BUILD_WITH_ANDROID_USERDEBUG)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 0
#endif
// Processor architecture detection. For more info on what's defined, see:
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
// http://www.agner.org/optimize/calling_conventions.pdf
// or with gcc, run: "echo | gcc -E -dM -"
#if defined(__aarch64__) ||
defined(_M_ARM64)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 0
#endif
#if defined(__x86_64__) ||
defined(_M_X64)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_X86_64() 0
#endif
// TODO(primiano): add a preprocessor macro to detect RISC-V on MSVC.
#if defined(__riscv)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_RISCV() 1
#else
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_RISCV() 0
#endif
// perfetto_build_flags.h contains the tweakable build flags defined via GN.
// - In GN builds (e.g., standalone, chromium, v8) this file is generated at
// build time via the gen_rule //gn/gen_buildflags.
// - In Android in-tree builds, this file is generated by tools/gen_android_bp
// and checked in into include/perfetto/base/build_configs/android_tree/. The
// default cflags add this path to the default include path.
// - Similarly, in bazel builds, this file is generated by tools/gen_bazel and
// checked in into include/perfetto/base/build_configs/bazel/.
// - In amalgamated builds, this file is generated by tools/gen_amalgamated and
// added to the amalgamated headers.
// gen_amalgamated expanded: #include "perfetto_build_flags.h" // no-include-violation-check
#endif // INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
// gen_amalgamated begin header: include/perfetto/base/logging.h
// gen_amalgamated begin header: include/perfetto/base/compiler.h
// gen_amalgamated begin header: include/perfetto/public/compiler.h
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
#define INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
#include <stddef.h>
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_LIKELY(_x) __builtin_expect(!!(_x), 1)
#define PERFETTO_UNLIKELY(_x) __builtin_expect(!!(_x), 0)
#else
#define PERFETTO_LIKELY(_x) (_x)
#define PERFETTO_UNLIKELY(_x) (_x)
#endif
// PERFETTO_STATIC_CAST(TYPE, VAL): avoids the -Wold-style-cast warning when
// writing code that needs to be compiled as C and C++.
#ifdef __cplusplus
#define PERFETTO_STATIC_CAST(TYPE, VAL)
static_cast<TYPE>(VAL)
#else
#define PERFETTO_STATIC_CAST(TYPE, VAL) ((TYPE)(VAL))
#endif
// PERFETTO_REINTERPRET_CAST(TYPE, VAL): avoids the -Wold-style-cast warning
// when writing code that needs to be compiled as C and C++.
#ifdef __cplusplus
#define PERFETTO_REINTERPRET_CAST(TYPE, VAL)
reinterpret_cast<TYPE>(VAL)
#else
#define PERFETTO_REINTERPRET_CAST(TYPE, VAL) ((TYPE)(VAL))
#endif
// PERFETTO_NULL: avoids the -Wzero-as-null-pointer-constant warning when
// writing code that needs to be compiled as C and C++.
#ifdef __cplusplus
#define PERFETTO_NULL nullptr
#else
#define PERFETTO_NULL NULL
#endif
#if defined(__clang__)
#define PERFETTO_ALWAYS_INLINE __attribute__((__always_inline__))
#define PERFETTO_NO_INLINE __attribute__((__noinline__))
#else
// GCC is too pedantic and often fails with the error:
// "always_inline function might not be inlinable"
#define PERFETTO_ALWAYS_INLINE
#define PERFETTO_NO_INLINE
#endif
#endif // INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_BASE_COMPILER_H_
#define INCLUDE_PERFETTO_BASE_COMPILER_H_
#include <cstddef>
#include <type_traits>
#include <variant>
// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
// __has_attribute is supported only by clang and recent versions of GCC.
// Add a layer to wrap the __has_attribute macro.
#if defined(__has_attribute)
#define PERFETTO_HAS_ATTRIBUTE(x) __has_attribute(x)
#else
#define PERFETTO_HAS_ATTRIBUTE(x) 0
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define PERFETTO_WARN_UNUSED_RESULT
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_UNUSED __attribute__((unused))
#else
#define PERFETTO_UNUSED
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_NORETURN __attribute__((__noreturn__))
#else
#define PERFETTO_NORETURN __declspec(noreturn)
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __FUNCSIG__
#else
#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() \
static_assert(
false,
"Not implemented for this compiler")
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_PRINTF_FORMAT(x, y) \
__attribute__((__format__(__printf__, x, y)))
#else
#define PERFETTO_PRINTF_FORMAT(x, y)
#endif
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_POPCOUNT(x) __builtin_popcountll(x)
#else
#include <intrin.h>
#define PERFETTO_POPCOUNT(x) __popcnt64(x)
#endif
#if defined(__clang__)
#if __has_feature(address_sanitizer) ||
defined(__SANITIZE_ADDRESS__)
#include "mozilla/MemoryChecking.h"
#define PERFETTO_ASAN_POISON(a, s) __asan_poison_memory_region((a), (s))
#define PERFETTO_ASAN_UNPOISON(a, s) __asan_unpoison_memory_region((a), (s))
#else
#define PERFETTO_ASAN_POISON(addr, size)
#define PERFETTO_ASAN_UNPOISON(addr, size)
#endif // __has_feature(address_sanitizer)
#else
#define PERFETTO_ASAN_POISON(addr, size)
#define PERFETTO_ASAN_UNPOISON(addr, size)
#endif // __clang__
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_IS_LITTLE_ENDIAN() __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#else
// Assume all MSVC targets are little endian.
#define PERFETTO_IS_LITTLE_ENDIAN() 1
#endif
// This is used for exporting xxxMain() symbols (e.g., PerfettoCmdMain,
// ProbesMain) from libperfetto.so when the GN arg monolithic_binaries = false.
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_EXPORT_ENTRYPOINT __attribute__((visibility(
"default")))
#else
// TODO(primiano): on Windows this should be a pair of dllexport/dllimport. But
// that requires a -DXXX_IMPLEMENTATION depending on whether we are on the
// impl-site or call-site. Right now it's not worth the trouble as we
// force-export the xxxMain() symbols only on Android, where we pack all the
// code for N binaries into one .so to save binary size. On Windows we support
// only monolithic binaries, as they are easier to deal with.
#define PERFETTO_EXPORT_ENTRYPOINT
#endif
// Disables undefined behavior analysis for a function.
#if defined(__clang__)
#define PERFETTO_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize(
"undefined")))
#else
#define PERFETTO_NO_SANITIZE_UNDEFINED
#endif
// Avoid calling the exit-time destructor on an object with static lifetime.
#if PERFETTO_HAS_ATTRIBUTE(no_destroy)
#define PERFETTO_HAS_NO_DESTROY() 1
#define PERFETTO_NO_DESTROY __attribute__((no_destroy))
#else
#define PERFETTO_HAS_NO_DESTROY() 0
#define PERFETTO_NO_DESTROY
#endif
// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
#define PERFETTO_FALLTHROUGH [[fallthrough]]
// Depending on the version of the compiler, __has_builtin can be provided or
// not.
#if defined(__has_builtin)
#if __has_builtin(__builtin_stack_address)
#define PERFETTO_HAS_BUILTIN_STACK_ADDRESS() 1
#else
#define PERFETTO_HAS_BUILTIN_STACK_ADDRESS() 0
#endif
#else
#define PERFETTO_HAS_BUILTIN_STACK_ADDRESS() 0
#endif
namespace perfetto::base {
template <
typename... T>
inline void ignore_result(
const T&...) {}
// Given a std::variant and a type T, returns the index of the T in the variant.
template <
typename VariantType,
typename T, size_t i = 0>
constexpr size_t variant_index() {
static_assert(i < std::variant_size_v<VariantType>,
"Type not found in variant");
if constexpr (std::is_same_v<std::variant_alternative_t<i, VariantType>, T>) {
return i;
}
else {
return variant_index<VariantType, T, i + 1>();
}
}
}
// namespace perfetto::base
#endif // INCLUDE_PERFETTO_BASE_COMPILER_H_
// gen_amalgamated begin header: include/perfetto/base/export.h
// gen_amalgamated begin header: include/perfetto/public/abi/export.h
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
#define INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
#ifdef _WIN32
#define PERFETTO_INTERNAL_DLL_EXPORT __declspec(dllexport)
#define PERFETTO_INTERNAL_DLL_IMPORT __declspec(dllimport)
#else
#define PERFETTO_INTERNAL_DLL_EXPORT __attribute__((visibility(
"default")))
#define PERFETTO_INTERNAL_DLL_IMPORT
#endif
// PERFETTO_SDK_EXPORT: Exports a symbol from the perfetto SDK shared library.
//
// This is controlled by two defines (that likely come from the compiler command
// line):
// * PERFETTO_SDK_DISABLE_SHLIB_EXPORT: If this is defined, no export
// annotations are added. This might be useful when static linking.
// * PERFETTO_SDK_SHLIB_IMPLEMENTATION: This must be defined when compiling the
// shared library itself (in order to export the symbols), but must be
// undefined when compiling objects that use the shared library (in order to
// import the symbols).
#if !
defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
#if defined(PERFETTO_SHLIB_SDK_IMPLEMENTATION)
#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_EXPORT
#else
#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_IMPORT
#endif
#else // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
#define PERFETTO_SDK_EXPORT
#endif // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
#endif // INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_BASE_EXPORT_H_
#define INCLUDE_PERFETTO_BASE_EXPORT_H_
// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/public/abi/export.h"
// PERFETTO_EXPORT_COMPONENT: Exports a symbol among C++ components when
// building with is_component = true (mostly used by chromium build).
#if PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
#if defined(PERFETTO_IMPLEMENTATION)
#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_EXPORT
#else
#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_IMPORT
#endif
#else // !PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
#if !
defined(PERFETTO_EXPORT_COMPONENT)
#define PERFETTO_EXPORT_COMPONENT
#endif // !defined(PERFETTO_EXPORT_COMPONENT)
#endif // PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
#endif // INCLUDE_PERFETTO_BASE_EXPORT_H_
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_BASE_LOGGING_H_
#define INCLUDE_PERFETTO_BASE_LOGGING_H_
#include <errno.h>
#include <string.h>
// For strerror.
// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
#if defined(__GNUC__) ||
defined(__clang__)
// Ignore GCC warning about a missing argument for a variadic macro parameter.
#pragma GCC system_header
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_ON)
#define PERFETTO_DCHECK_IS_ON() 1
#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_OFF)
#define PERFETTO_DCHECK_IS_ON() 0
#elif defined(DCHECK_ALWAYS_ON) || \
(!
defined(NDEBUG) && (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD) || \
PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)))
#define PERFETTO_DCHECK_IS_ON() 1
#else
#define PERFETTO_DCHECK_IS_ON() 0
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
#define PERFETTO_DLOG_IS_ON() 1
#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_OFF)
#define PERFETTO_DLOG_IS_ON() 0
#else
#define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON()
#endif
#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
!PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
#error "Async-safe logging is limited to Android tree builds"
#endif
// For binaries which need a very lightweight logging implementation.
// Note that this header is incompatible with android/log.h.
#include <async_safe/log.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Normal android logging.
#include <android/log.h>
#endif
// Enable the "Print the most recent PERFETTO_LOG(s) before crashing" feature
// on Android in-tree builds and on standalone builds (mainly for testing).
// This is deliberately no PERFETTO_OS_ANDROID because we don't want this
// feature when perfetto is embedded in other Android projects (e.g. SDK).
// TODO(b/203795298): TFLite is using the client library in blaze builds and is
// targeting API 19. For now disable the feature based on API level.
#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
#elif PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
#elif PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
(!PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
(
defined(__ANDROID_API__) && __ANDROID_API__ >= 21))
#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
#else
#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
#endif
namespace perfetto {
namespace base {
// Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
constexpr
const char* StrEnd(
const char* s) {
return *s ? StrEnd(s + 1) : s;
}
constexpr
const char* BasenameRecursive(
const char* s,
const char* begin,
const char* end) {
return (*s ==
'/' && s < end)
? (s + 1)
: ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
}
constexpr
const char* Basename(
const char* str) {
return BasenameRecursive(StrEnd(str), str, StrEnd(str));
}
enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
struct LogMessageCallbackArgs {
LogLev level;
int line;
const char* filename;
const char* message;
};
using LogMessageCallback =
void (*)(LogMessageCallbackArgs);
// This is not thread safe and must be called before using tracing from other
// threads.
PERFETTO_EXPORT_COMPONENT
void SetLogMessageCallback(
LogMessageCallback callback);
PERFETTO_EXPORT_COMPONENT
void LogMessage(LogLev,
const char* fname,
int line,
const char* fmt,
...) PERFETTO_PRINTF_FORMAT(4, 5);
// This is defined in debug_crash_stack_trace.cc, but that is only linked in
// standalone && debug builds, see enable_perfetto_stderr_crash_dump in
// perfetto.gni.
PERFETTO_EXPORT_COMPONENT
void EnableStacktraceOnCrashForDebug();
#if PERFETTO_ENABLE_LOG_RING_BUFFER()
// Gets a snapshot of the logs from the internal log ring buffer and:
// - On Android in-tree builds: Passes that to android_set_abort_message().
// That will attach the logs to the crash report.
// - On standalone builds (all otther OSes) prints that on stderr.
// This function must called only once, right before inducing a crash (This is
// because android_set_abort_message() can only be called once).
PERFETTO_EXPORT_COMPONENT
void MaybeSerializeLastLogsForCrashReporting();
#else
inline void MaybeSerializeLastLogsForCrashReporting() {}
#endif
#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
#define PERFETTO_XLOG(level, fmt, ...) \
do { \
async_safe_format_log((ANDROID_LOG_DEBUG + level),
"perfetto", \
"%s:%d " fmt, ::perfetto::base::Basename(__FILE__), \
__LINE__,
##__VA_ARGS__); \
}
while (0)
#elif defined(PERFETTO_DISABLE_LOG)
#define PERFETTO_XLOG(level, fmt, ...) \
::perfetto::base::ignore_result(level, fmt,
##__VA_ARGS__)
#else
#define PERFETTO_XLOG(level, fmt, ...) \
::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
__LINE__, fmt,
##__VA_ARGS__)
#endif
#if defined(_MSC_VER)
#define PERFETTO_IMMEDIATE_CRASH() \
do { \
::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
__debugbreak(); \
__assume(0); \
}
while (0)
#else
#define PERFETTO_IMMEDIATE_CRASH() \
do { \
::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
__builtin_trap(); \
__builtin_unreachable(); \
}
while (0)
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
#define PERFETTO_LOG(fmt, ...) \
PERFETTO_XLOG(::perfetto::base::kLogInfo, fmt,
##__VA_ARGS__)
#else // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
#define PERFETTO_LOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
#endif // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
#define PERFETTO_ILOG(fmt, ...) \
PERFETTO_XLOG(::perfetto::base::kLogImportant, fmt,
##__VA_ARGS__)
#define PERFETTO_ELOG(fmt, ...) \
PERFETTO_XLOG(::perfetto::base::kLogError, fmt,
##__VA_ARGS__)
#define PERFETTO_FATAL(fmt, ...) \
do { \
PERFETTO_PLOG(fmt,
##__VA_ARGS__); \
PERFETTO_IMMEDIATE_CRASH(); \
}
while (0)
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_PLOG(x, ...) \
PERFETTO_ELOG(x
" (errno: %d, %s)",
##__VA_ARGS__, errno, strerror(errno))
#else
// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
#define PERFETTO_PLOG PERFETTO_ELOG
#endif
#define PERFETTO_CHECK(x) \
do { \
if (PERFETTO_UNLIKELY(!(x))) { \
PERFETTO_PLOG(
"%s",
"PERFETTO_CHECK(" #x ")"); \
PERFETTO_IMMEDIATE_CRASH(); \
} \
}
while (0)
#if PERFETTO_DLOG_IS_ON()
#define PERFETTO_DLOG(fmt, ...) \
PERFETTO_XLOG(::perfetto::base::kLogDebug, fmt,
##__VA_ARGS__)
#if defined(__GNUC__) ||
defined(__clang__)
#define PERFETTO_DPLOG(x, ...) \
PERFETTO_DLOG(x
" (errno: %d, %s)",
##__VA_ARGS__, errno, strerror(errno))
#else
// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
#define PERFETTO_DPLOG PERFETTO_DLOG
#endif
#else // PERFETTO_DLOG_IS_ON()
#define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
#define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
#endif // PERFETTO_DLOG_IS_ON()
#if PERFETTO_DCHECK_IS_ON()
#define PERFETTO_DCHECK(x) PERFETTO_CHECK(x)
#define PERFETTO_DFATAL(...) PERFETTO_FATAL(__VA_ARGS__)
#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
#else // PERFETTO_DCHECK_IS_ON()
#define PERFETTO_DCHECK(x) \
do { \
}
while (
false && (x))
#define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
#endif // PERFETTO_DCHECK_IS_ON()
}
// namespace base
}
// namespace perfetto
#endif // INCLUDE_PERFETTO_BASE_LOGGING_H_
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_BASE_TIME_H_
#define INCLUDE_PERFETTO_BASE_TIME_H_
#include <stdint.h>
#include <time.h>
#include <chrono>
#include <optional>
#include <string>
// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#include <mach/mach_time.h>
#include <mach/thread_act.h>
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
#include <emscripten/emscripten.h>
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
#include <intrin.h>
#endif
#endif
namespace perfetto {
namespace base {
using TimeSeconds = std::chrono::seconds;
using TimeMillis = std::chrono::milliseconds;
using TimeNanos = std::chrono::nanoseconds;
inline TimeNanos FromPosixTimespec(
const struct timespec& ts) {
return TimeNanos(ts.tv_sec * 1000000000LL + ts.tv_nsec);
}
void SleepMicroseconds(
unsigned interval_us);
void InitializeTime();
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
TimeNanos GetWallTimeNs();
TimeNanos GetThreadCPUTimeNs();
inline TimeNanos GetWallTimeRawNs() {
return GetWallTimeNs();
}
// TODO: Clock that counts time during suspend is not implemented on Windows.
inline TimeNanos GetBootTimeNs() {
return GetWallTimeNs();
}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
inline TimeNanos GetWallTimeNs() {
auto init_timebase_info = []() -> mach_timebase_info_data_t {
mach_timebase_info_data_t timebase_info;
mach_timebase_info(&timebase_info);
return timebase_info;
};
static mach_timebase_info_data_t timebase_info = init_timebase_info();
uint64_t mach_time = mach_absolute_time();
// Take the fast path when the conversion is 1:1. The result will for sure fit
// into an int_64 because we're going from nanoseconds to microseconds.
if (timebase_info.numer == timebase_info.denom) {
return TimeNanos(mach_time);
}
// Nanoseconds is mach_time * timebase.numer // timebase.denom. Divide first
// to reduce the chance of overflow. Also stash the remainder right now,
// a likely byproduct of the division.
uint64_t nanoseconds = mach_time / timebase_info.denom;
const uint64_t mach_time_remainder = mach_time % timebase_info.denom;
// Now multiply, keeping an eye out for overflow.
PERFETTO_CHECK(!__builtin_umulll_overflow(nanoseconds, timebase_info.numer,
&nanoseconds));
// By dividing first we lose precision. Regain it by adding back the
// nanoseconds from the remainder, with an eye out for overflow.
uint64_t least_significant_nanoseconds =
(mach_time_remainder * timebase_info.numer) / timebase_info.denom;
PERFETTO_CHECK(!__builtin_uaddll_overflow(
nanoseconds, least_significant_nanoseconds, &nanoseconds));
return TimeNanos(nanoseconds);
}
inline TimeNanos GetWallTimeRawNs() {
return GetWallTimeNs();
}
// TODO: Clock that counts time during suspend is not implemented on Mac.
inline TimeNanos GetBootTimeNs() {
return GetWallTimeNs();
}
// Before MacOS 10.12 clock_gettime() was not implemented.
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101200
inline TimeNanos GetThreadCPUTimeNs() {
mach_port_t this_thread = mach_thread_self();
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info{};
kern_return_t kr =
thread_info(this_thread, THREAD_BASIC_INFO,
reinterpret_cast<thread_info_t>(&info), &count);
mach_port_deallocate(mach_task_self(), this_thread);
if (kr != KERN_SUCCESS) {
PERFETTO_DFATAL(
"Failed to get CPU time.");
return TimeNanos(0);
}
return TimeNanos(info.user_time.seconds * 1000000000LL +
info.user_time.microseconds * 1000LL +
info.system_time.seconds * 1000000000LL +
info.system_time.microseconds * 1000LL);
}
#else
inline TimeNanos GetThreadCPUTimeNs() {
struct timespec ts = {};
PERFETTO_CHECK(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0);
return FromPosixTimespec(ts);
}
#endif
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
inline TimeNanos GetWallTimeNs() {
return TimeNanos(
static_cast<uint64_t>(emscripten_get_now()) * 1000000);
}
inline TimeNanos GetWallTimeRawNs() {
return GetWallTimeNs();
}
inline TimeNanos GetThreadCPUTimeNs() {
return TimeNanos(0);
}
// TODO: Clock that counts time during suspend is not implemented on WASM.
inline TimeNanos GetBootTimeNs() {
return GetWallTimeNs();
}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
// Tracing time doesn't need to work on NaCl since its going away shortly. We
// just need to compile on it. The only function NaCl could support is
// GetWallTimeNs(), but to prevent false hope we leave it unimplemented.
inline TimeNanos GetWallTimeNs() {
return TimeNanos(0);
}
inline TimeNanos GetWallTimeRawNs() {
return TimeNanos(0);
}
inline TimeNanos GetThreadCPUTimeNs() {
return TimeNanos(0);
}
inline TimeNanos GetBootTimeNs() {
return TimeNanos(0);
}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
inline TimeNanos GetTimeInternalNs(clockid_t clk_id) {
struct timespec ts = {};
PERFETTO_CHECK(clock_gettime(clk_id, &ts) == 0);
return FromPosixTimespec(ts);
}
inline TimeNanos GetWallTimeNs() {
return GetTimeInternalNs(kWallTimeClockSource);
}
inline TimeNanos GetWallTimeRawNs() {
return GetTimeInternalNs(CLOCK_MONOTONIC);
}
inline TimeNanos GetThreadCPUTimeNs() {
return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
}
// TODO: Clock that counts time during suspend is not implemented on QNX.
inline TimeNanos GetBootTimeNs() {
return GetWallTimeNs();
}
#else // posix
constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
inline TimeNanos GetTimeInternalNs(clockid_t clk_id) {
struct timespec ts = {};
PERFETTO_CHECK(clock_gettime(clk_id, &ts) == 0);
return FromPosixTimespec(ts);
}
// Return ns from boot. Conversely to GetWallTimeNs, this clock counts also time
// during suspend (when supported).
inline TimeNanos GetBootTimeNs() {
// Determine if CLOCK_BOOTTIME is available on the first call.
static const clockid_t kBootTimeClockSource = [] {
struct timespec ts = {};
int res = clock_gettime(CLOCK_BOOTTIME, &ts);
return res == 0 ? CLOCK_BOOTTIME : kWallTimeClockSource;
}();
return GetTimeInternalNs(kBootTimeClockSource);
}
inline TimeNanos GetWallTimeNs() {
return GetTimeInternalNs(kWallTimeClockSource);
}
inline TimeNanos GetWallTimeRawNs() {
return GetTimeInternalNs(CLOCK_MONOTONIC_RAW);
}
inline TimeNanos GetThreadCPUTimeNs() {
return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
}
#endif
inline TimeSeconds GetBootTimeS() {
return std::chrono::duration_cast<TimeSeconds>(GetBootTimeNs());
}
inline TimeMillis GetBootTimeMs() {
return std::chrono::duration_cast<TimeMillis>(GetBootTimeNs());
}
inline TimeMillis GetWallTimeMs() {
return std::chrono::duration_cast<TimeMillis>(GetWallTimeNs());
}
inline TimeSeconds GetWallTimeS() {
return std::chrono::duration_cast<TimeSeconds>(GetWallTimeNs());
}
inline struct timespec ToPosixTimespec(TimeMillis time) {
struct timespec ts {};
const long time_s =
static_cast<
long>(time.count() / 1000);
ts.tv_sec = time_s;
ts.tv_nsec = (
static_cast<
long>(time.count()) - time_s * 1000L) * 1000000L;
return ts;
}
std::string GetTimeFmt(
const std::string& fmt);
inline int64_t TimeGm(
struct tm* tms) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
return static_cast<int64_t>(_mkgmtime(tms));
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
// NaCL has no timegm.
if (tms)
// Kinda if (true), but avoids "mark as noreturn" errors.
PERFETTO_FATAL(
"timegm not supported");
return -1;
#else
return static_cast<int64_t>(timegm(tms));
#endif
}
// Creates a time_t-compatible timestamp (seconds since epoch) from a tuple of
// y-m-d-h-m-s. It's a saner version of timegm(). Some remarks:
// The year is just the actual year (it's Y-1900 in timegm()).
// The month ranges 1-12 (it's 0-11 in timegm()).
inline int64_t MkTime(
int year,
int month,
int day,
int h,
int m,
int s) {
PERFETTO_DCHECK(year >= 1900);
PERFETTO_DCHECK(month > 0 && month <= 12);
PERFETTO_DCHECK(day > 0 && day <= 31);
struct tm tms {};
tms.tm_year = year - 1900;
tms.tm_mon = month - 1;
tms.tm_mday = day;
tms.tm_hour = h;
tms.tm_min = m;
tms.tm_sec = s;
return TimeGm(&tms);
}
#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
inline uint64_t Rdtsc() {
#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
return static_cast<uint64_t>(__rdtsc());
#else
// Use inline asm for clang and gcc: rust ffi bindgen crashes in using
// intrinsics on ChromeOS.
uint64_t low, high;
__asm__
volatile(
"rdtsc" :
"=a"(low),
"=d"(high));
return (high << 32) | low;
#endif
}
#endif
std::optional<int32_t> GetTimezoneOffsetMins();
}
// namespace base
}
// namespace perfetto
#endif // INCLUDE_PERFETTO_BASE_TIME_H_
// gen_amalgamated begin header: include/perfetto/tracing/buffer_exhausted_policy.h
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
#define INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
namespace perfetto {
// Determines how SharedMemoryArbiterImpl::GetNewChunk() behaves when no free
// chunks are available.
enum class BufferExhaustedPolicy {
// SharedMemoryArbiterImpl::GetNewChunk() will stall if no free SMB chunk is
// available and wait for the tracing service to free one. Note that this
// requires that messages the arbiter sends to the tracing service (from any
// TraceWriter thread) will be received by it, even if all TraceWriter threads
// are stalled.
kStall,
// SharedMemoryArbiterImpl::GetNewChunk() will return an invalid chunk if no
// free SMB chunk is available. In this case, the TraceWriter will fall back
// to a garbage chunk and drop written data until acquiring a future chunk
// succeeds again.
kDrop,
// TODO(eseckler): Switch to kDrop by default and change the Android code to
// explicitly request kStall instead.
kDefault = kStall
};
}
// namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
// gen_amalgamated begin header: include/perfetto/tracing/console_interceptor.h
// gen_amalgamated begin header: include/perfetto/tracing/interceptor.h
// gen_amalgamated begin header: include/perfetto/protozero/field.h
// gen_amalgamated begin header: include/perfetto/protozero/contiguous_memory_range.h
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
#define INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
namespace protozero {
// Keep this struct trivially constructible (no ctors, no default initializers).
struct ContiguousMemoryRange {
uint8_t* begin;
uint8_t* end;
// STL style: one byte past the end of the buffer.
inline bool is_valid()
const {
return begin != nullptr; }
inline void reset() { begin = nullptr; }
inline size_t size()
const {
return static_cast<size_t>(end - begin); }
};
}
// namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
// gen_amalgamated begin header: include/perfetto/protozero/proto_utils.h
// gen_amalgamated begin header: include/perfetto/public/pb_utils.h
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
#define INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
#include <assert.h>
#include <stdint.h>
#include <string.h>
// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
// Type of fields that can be found in a protobuf serialized message.
enum PerfettoPbWireType {
PERFETTO_PB_WIRE_TYPE_VARINT = 0,
PERFETTO_PB_WIRE_TYPE_FIXED64 = 1,
PERFETTO_PB_WIRE_TYPE_DELIMITED = 2,
PERFETTO_PB_WIRE_TYPE_FIXED32 = 5,
};
// Creates a field tag, which encodes the field type and the field id.
static inline uint32_t PerfettoPbMakeTag(int32_t field_id,
enum PerfettoPbWireType wire_type) {
return ((PERFETTO_STATIC_CAST(uint32_t, field_id)) << 3) |
PERFETTO_STATIC_CAST(uint32_t, wire_type);
}
enum {
// Maximum bytes size of a 64-bit integer encoded as a VarInt.
PERFETTO_PB_VARINT_MAX_SIZE_64 = 10,
// Maximum bytes size of a 32-bit integer encoded as a VarInt.
PERFETTO_PB_VARINT_MAX_SIZE_32 = 5,
};
// Encodes `value` as a VarInt into `*dst`.
//
// `dst` must point into a buffer big enough to represent `value`:
// PERFETTO_PB_VARINT_MAX_SIZE_* can help.
static inline uint8_t* PerfettoPbWriteVarInt(uint64_t value, uint8_t* dst) {
uint8_t byte;
while (value >= 0x80) {
byte = (value & 0x7f) | 0x80;
*dst++ = byte;
value >>= 7;
}
byte = value & 0x7f;
*dst++ = byte;
return dst;
}
// Encodes `value` as a fixed32 (little endian) into `*dst`.
//
// `dst` must point into a buffer with at least 4 bytes of space.
static inline uint8_t* PerfettoPbWriteFixed32(uint32_t value, uint8_t* buf) {
buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
return buf + 4;
}
// Encodes `value` as a fixed32 (little endian) into `*dst`.
//
// `dst` must point into a buffer with at least 8 bytes of space.
static inline uint8_t* PerfettoPbWriteFixed64(uint64_t value, uint8_t* buf) {
buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
buf[4] = PERFETTO_STATIC_CAST(uint8_t, value >> 32);
buf[5] = PERFETTO_STATIC_CAST(uint8_t, value >> 40);
buf[6] = PERFETTO_STATIC_CAST(uint8_t, value >> 48);
buf[7] = PERFETTO_STATIC_CAST(uint8_t, value >> 56);
return buf + 8;
}
// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
// points one byte past the end of buffer.
// The parsed int value is stored in the output arg |value|. Returns a pointer
// to the next unconsumed byte (so start < retval <= end) or |start| if the
// VarInt could not be fully parsed because there was not enough space in the
// buffer.
static inline const uint8_t* PerfettoPbParseVarInt(
const uint8_t* start,
const uint8_t* end,
uint64_t* out_value) {
const uint8_t* pos = start;
uint64_t value = 0;
for (uint32_t shift = 0; pos < end && shift < 64u; shift += 7) {
// Cache *pos into |cur_byte| to prevent that the compiler dereferences the
// pointer twice (here and in the if() below) due to char* aliasing rules.
uint8_t cur_byte = *pos++;
value |= PERFETTO_STATIC_CAST(uint64_t, cur_byte & 0x7f) << shift;
if ((cur_byte & 0x80) == 0) {
// In valid cases we get here.
*out_value = value;
return pos;
}
}
*out_value = 0;
return start;
}
static inline uint32_t PerfettoPbZigZagEncode32(int32_t value) {
#if defined(__cplusplus) || \
(
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
// Right-shift of negative values is implementation specific.
// Assert the implementation does what we expect, which is that shifting an
// positive int32_t by 31 gives an all 0 bitmap, and a negative int32_t gives
// an all 1 bitmap.
static_assert(
PERFETTO_STATIC_CAST(uint32_t, INT32_C(-1) >> 31) == ~UINT32_C(0),
"implementation does not support assumed rightshift");
static_assert(PERFETTO_STATIC_CAST(uint32_t, INT32_C(1) >> 31) == UINT32_C(0),
"implementation does not support assumed rightshift");
#endif
return (PERFETTO_STATIC_CAST(uint32_t, value) << 1) ^
PERFETTO_STATIC_CAST(uint32_t, value >> 31);
}
static inline uint64_t PerfettoPbZigZagEncode64(int64_t value) {
#if defined(__cplusplus) || \
(
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
// Right-shift of negative values is implementation specific.
// Assert the implementation does what we expect, which is that shifting an
// positive int64_t by 63 gives an all 0 bitmap, and a negative int64_t gives
// an all 1 bitmap.
static_assert(
PERFETTO_STATIC_CAST(uint64_t, INT64_C(-1) >> 63) == ~UINT64_C(0),
"implementation does not support assumed rightshift");
static_assert(PERFETTO_STATIC_CAST(uint64_t, INT64_C(1) >> 63) == UINT64_C(0),
"implementation does not support assumed rightshift");
#endif
return (PERFETTO_STATIC_CAST(uint64_t, value) << 1) ^
PERFETTO_STATIC_CAST(uint64_t, value >> 63);
}
static inline int32_t PerfettoPbZigZagDecode32(uint32_t value) {
uint32_t mask =
PERFETTO_STATIC_CAST(uint32_t, -PERFETTO_STATIC_CAST(int32_t, value & 1));
return PERFETTO_STATIC_CAST(int32_t, ((value >> 1) ^ mask));
}
static inline int64_t PerfettoPbZigZagDecode64(uint64_t value) {
uint64_t mask =
PERFETTO_STATIC_CAST(uint64_t, -PERFETTO_STATIC_CAST(int64_t, value & 1));
return PERFETTO_STATIC_CAST(int64_t, ((value >> 1) ^ mask));
}
static inline uint64_t PerfettoPbDoubleToFixed64(
double value) {
uint64_t val;
memcpy(&val, &value,
sizeof val);
return val;
}
static inline uint32_t PerfettoPbFloatToFixed32(
float value) {
uint32_t val;
memcpy(&val, &value,
sizeof val);
return val;
}
#endif // INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
#define INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
#include <stddef.h>
#include <cinttypes>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/public/pb_utils.h"
// Helper macro for the constexpr functions containing
// the switch statement: if C++14 is supported, this macro
// resolves to `constexpr` and just `inline` otherwise.
#if __cpp_constexpr >= 201304
#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE constexpr
#else
#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
inline
#endif
namespace protozero {
namespace proto_utils {
// See https://developers.google.com/protocol-buffers/docs/encoding wire types.
// This is a type encoded into the proto that provides just enough info to
// find the length of the following value.
enum class ProtoWireType : uint32_t {
kVarInt = 0,
kFixed64 = 1,
kLengthDelimited = 2,
kFixed32 = 5,
};
// This is the type defined in the proto for each field. This information
// is used to decide the translation strategy when writing the trace.
enum class ProtoSchemaType {
kUnknown = 0,
kDouble,
kFloat,
kInt64,
kUint64,
kInt32,
kFixed64,
kFixed32,
kBool,
kString,
kGroup,
// Deprecated (proto2 only)
kMessage,
kBytes,
kUint32,
kEnum,
kSfixed32,
kSfixed64,
kSint32,
kSint64,
};
inline const char* ProtoSchemaToString(ProtoSchemaType v) {
switch (v) {
case ProtoSchemaType::kUnknown:
return "unknown";
case ProtoSchemaType::kDouble:
return "double";
case ProtoSchemaType::kFloat:
return "float";
case ProtoSchemaType::kInt64:
return "int64";
case ProtoSchemaType::kUint64:
return "uint64";
case ProtoSchemaType::kInt32:
return "int32";
case ProtoSchemaType::kFixed64:
return "fixed64";
case ProtoSchemaType::kFixed32:
return "fixed32";
case ProtoSchemaType::kBool:
return "bool";
case ProtoSchemaType::kString:
return "string";
case ProtoSchemaType::kGroup:
return "group";
case ProtoSchemaType::kMessage:
return "message";
case ProtoSchemaType::kBytes:
return "bytes";
case ProtoSchemaType::kUint32:
return "uint32";
case ProtoSchemaType::kEnum:
return "enum";
case ProtoSchemaType::kSfixed32:
return "sfixed32";
case ProtoSchemaType::kSfixed64:
return "sfixed64";
case ProtoSchemaType::kSint32:
return "sint32";
case ProtoSchemaType::kSint64:
return "sint64";
}
// For gcc:
PERFETTO_DCHECK(
false);
return "";
}
// Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding).
constexpr size_t kMessageLengthFieldSize = 4;
constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
constexpr size_t kMaxOneByteMessageLength = (1 << 7) - 1;
// Field tag is encoded as 32-bit varint (5 bytes at most).
// Largest value of simple (not length-delimited) field is 64-bit varint
// (10 bytes at most). 15 bytes buffer is enough to store a simple field.
constexpr size_t kMaxTagEncodedSize = 5;
constexpr size_t kMaxSimpleFieldEncodedSize = kMaxTagEncodedSize + 10;
// Proto types: (int|uint|sint)(32|64), bool, enum.
constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
return (field_id << 3) |
static_cast<uint32_t>(ProtoWireType::kVarInt);
}
// Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
template <
typename T>
constexpr uint32_t MakeTagFixed(uint32_t field_id) {
static_assert(
sizeof(T) == 8 ||
sizeof(T) == 4,
"Value must be 4 or 8 bytes");
return (field_id << 3) |
static_cast<uint32_t>((
sizeof(T) == 8 ? ProtoWireType::kFixed64
: ProtoWireType::kFixed32));
}
// Proto types: string, bytes, embedded messages.
constexpr uint32_t MakeTagLengthDelimited(uint32_t field_id) {
return (field_id << 3) |
static_cast<uint32_t>(ProtoWireType::kLengthDelimited);
}
// Proto types: sint64, sint32.
template <
typename T>
inline typename std::make_unsigned<T>::type ZigZagEncode(T value) {
using UnsignedType =
typename std::make_unsigned<T>::type;
// Right-shift of negative values is implementation specific.
// Assert the implementation does what we expect, which is that shifting any
// positive value by sizeof(T) * 8 - 1 gives an all 0 bitmap, and a negative
// value gives an all 1 bitmap.
constexpr uint64_t kUnsignedZero = 0u;
constexpr int64_t kNegativeOne = -1;
constexpr int64_t kPositiveOne = 1;
static_assert(
static_cast<uint64_t>(kNegativeOne >> 63) == ~kUnsignedZero,
"implementation does not support assumed rightshift");
static_assert(
static_cast<uint64_t>(kPositiveOne >> 63) == kUnsignedZero,
"implementation does not support assumed rightshift");
return (
static_cast<UnsignedType>(value) << 1) ^
static_cast<UnsignedType>(value >> (
sizeof(T) * 8 - 1));
}
// Proto types: sint64, sint32.
template <
typename T>
inline typename std::make_signed<T>::type ZigZagDecode(T value) {
using UnsignedType =
typename std::make_unsigned<T>::type;
using SignedType =
typename std::make_signed<T>::type;
auto u_value =
static_cast<UnsignedType>(value);
auto mask =
static_cast<UnsignedType>(-
static_cast<SignedType>(u_value & 1));
return static_cast<SignedType>((u_value >> 1) ^ mask);
}
template <
typename T>
auto ExtendValueForVarIntSerialization(T value) ->
typename std::make_unsigned<
typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type>::
type {
// If value is <= 0 we must first sign extend to int64_t (see [1]).
// Finally we always cast to an unsigned value to to avoid arithmetic
// (sign expanding) shifts in the while loop.
// [1]: "If you use int32 or int64 as the type for a negative number, the
// resulting varint is always ten bytes long".
// - developers.google.com/protocol-buffers/docs/encoding
// So for each input type we do the following casts:
// uintX_t -> uintX_t -> uintX_t
// int8_t -> int64_t -> uint64_t
// int16_t -> int64_t -> uint64_t
// int32_t -> int64_t -> uint64_t
// int64_t -> int64_t -> uint64_t
using MaybeExtendedType =
typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type;
using UnsignedType =
typename std::make_unsigned<MaybeExtendedType>::type;
MaybeExtendedType extended_value =
static_cast<MaybeExtendedType>(value);
UnsignedType unsigned_value =
static_cast<UnsignedType>(extended_value);
return unsigned_value;
}
template <
typename T>
inline uint8_t* WriteVarInt(T value, uint8_t* target) {
auto unsigned_value = ExtendValueForVarIntSerialization(value);
while (unsigned_value >= 0x80) {
*target++ =
static_cast<uint8_t>(unsigned_value) | 0x80;
unsigned_value >>= 7;
}
*target =
static_cast<uint8_t>(unsigned_value);
return target + 1;
}
// Writes a fixed-size redundant encoding of the given |value|. This is
// used to backfill fixed-size reservations for the length field using a
// non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
// See https://github.com/google/protobuf/issues/1530.
// This is used mainly in two cases:
// 1) At trace writing time, when starting a nested messages. The size of a
// nested message is not known until all its field have been written.
// |kMessageLengthFieldSize| bytes are reserved to encode the size field and
// backfilled at the end.
// 2) When rewriting a message at trace filtering time, in protozero/filtering.
// At that point we know only the upper bound of the length (a filtered
// message is <= the original one) and we backfill after the message has been
// filtered.
inline void WriteRedundantVarInt(uint32_t value,
uint8_t* buf,
size_t size = kMessageLengthFieldSize) {
for (size_t i = 0; i < size; ++i) {
const uint8_t msb = (i < size - 1) ? 0x80 : 0;
buf[i] =
static_cast<uint8_t>(value) | msb;
value >>= 7;
}
}
template <uint32_t field_id>
void StaticAssertSingleBytePreamble() {
static_assert(field_id < 16,
"Proto field id too big to fit in a single byte preamble");
}
// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
// points one byte past the end of buffer.
// The parsed int value is stored in the output arg |value|. Returns a pointer
// to the next unconsumed byte (so start < retval <= end) or |start| if the
// VarInt could not be fully parsed because there was not enough space in the
// buffer.
inline const uint8_t* ParseVarInt(
const uint8_t* start,
const uint8_t* end,
uint64_t* out_value) {
return PerfettoPbParseVarInt(start, end, out_value);
}
enum class RepetitionType {
kNotRepeated,
kRepeatedPacked,
kRepeatedNotPacked,
};
// Provide a common base struct for all templated FieldMetadata types to allow
// simple checks if a given type is a FieldMetadata or not.
struct FieldMetadataBase {
constexpr FieldMetadataBase() =
default;
};
template <uint32_t field_id,
RepetitionType repetition_type,
ProtoSchemaType proto_schema_type,
typename CppFieldType,
typename MessageType>
struct FieldMetadata :
public FieldMetadataBase {
constexpr FieldMetadata() =
default;
static constexpr
int kFieldId = field_id;
// Whether this field is repeated, packed (repeated [packed-true]) or not
// (optional).
static constexpr RepetitionType kRepetitionType = repetition_type;
// Proto type of this field (e.g. int64, fixed32 or nested message).
static constexpr ProtoSchemaType kProtoFieldType = proto_schema_type;
// C++ type of this field (for nested messages - C++ protozero class).
using cpp_field_type = CppFieldType;
// Protozero message which this field belongs to.
using message_type = MessageType;
};
}
// namespace proto_utils
}
// namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
#define INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
#include <stdint.h>
#include <string>
#include <string_view>
#include <vector>
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
namespace protozero {
struct ConstBytes {
std::string ToStdString()
const {
return std::string(
reinterpret_cast<
const char*>(data), size);
}
const uint8_t* data;
size_t size;
};
struct ConstChars {
--> --------------------
--> maximum size reached
--> --------------------