// 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 {
// Allow implicit conversion to perfetto's base::StringView without depending
// on perfetto/base or viceversa.
static constexpr
bool kConvertibleToStringView =
true;
static constexpr
bool kHashable =
true;
std::string ToStdString()
const {
return {data, size}; }
std::string_view ToStdStringView()
const {
return {data, size}; }
const char* data;
size_t size;
};
// A protobuf field decoded by the protozero proto decoders. It exposes
// convenience accessors with minimal debug checks.
// This class is used both by the iterator-based ProtoDecoder and by the
// one-shot TypedProtoDecoder.
// If the field is not valid the accessors consistently return zero-integers or
// null strings.
class Field {
public:
bool valid()
const {
return id_ != 0; }
uint32_t id()
const {
return id_; }
explicit operator bool()
const {
return valid(); }
proto_utils::ProtoWireType type()
const {
auto res =
static_cast<proto_utils::ProtoWireType>(type_);
PERFETTO_DCHECK(res == proto_utils::ProtoWireType::kVarInt ||
res == proto_utils::ProtoWireType::kLengthDelimited ||
res == proto_utils::ProtoWireType::kFixed32 ||
res == proto_utils::ProtoWireType::kFixed64);
return res;
}
bool as_bool()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
return static_cast<
bool>(int_value_);
}
uint32_t as_uint32()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
type() == proto_utils::ProtoWireType::kFixed32);
return static_cast<uint32_t>(int_value_);
}
int32_t as_int32()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
type() == proto_utils::ProtoWireType::kFixed32);
return static_cast<int32_t>(int_value_);
}
int32_t as_sint32()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
return proto_utils::ZigZagDecode(
static_cast<uint32_t>(int_value_));
}
uint64_t as_uint64()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
type() == proto_utils::ProtoWireType::kFixed32 ||
type() == proto_utils::ProtoWireType::kFixed64);
return int_value_;
}
int64_t as_int64()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
type() == proto_utils::ProtoWireType::kFixed32 ||
type() == proto_utils::ProtoWireType::kFixed64);
return static_cast<int64_t>(int_value_);
}
int64_t as_sint64()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
return proto_utils::ZigZagDecode(
static_cast<uint64_t>(int_value_));
}
float as_float()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed32);
float res;
uint32_t value32 =
static_cast<uint32_t>(int_value_);
memcpy(&res, &value32,
sizeof(res));
return res;
}
double as_double()
const {
PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed64);
double res;
memcpy(&res, &int_value_,
sizeof(res));
return res;
}
ConstChars as_string()
const {
PERFETTO_DCHECK(!valid() ||
type() == proto_utils::ProtoWireType::kLengthDelimited);
return ConstChars{
reinterpret_cast<
const char*>(data()), size_};
}
std::string as_std_string()
const {
return as_string().ToStdString(); }
ConstBytes as_bytes()
const {
PERFETTO_DCHECK(!valid() ||
type() == proto_utils::ProtoWireType::kLengthDelimited);
return ConstBytes{data(), size_};
}
const uint8_t* data()
const {
PERFETTO_DCHECK(!valid() ||
type() == proto_utils::ProtoWireType::kLengthDelimited);
return reinterpret_cast<
const uint8_t*>(int_value_);
}
size_t size()
const {
PERFETTO_DCHECK(!valid() ||
type() == proto_utils::ProtoWireType::kLengthDelimited);
return size_;
}
uint64_t raw_int_value()
const {
return int_value_; }
void initialize(uint32_t id,
uint8_t type,
uint64_t int_value,
uint32_t size) {
id_ = id & kMaxId;
type_ = type;
int_value_ = int_value;
size_ = size;
}
// For use with templates. This is used by RepeatedFieldIterator::operator*().
void get(
bool* val)
const { *val = as_bool(); }
void get(uint32_t* val)
const { *val = as_uint32(); }
void get(int32_t* val)
const { *val = as_int32(); }
void get(uint64_t* val)
const { *val = as_uint64(); }
void get(int64_t* val)
const { *val = as_int64(); }
void get(
float* val)
const { *val = as_float(); }
void get(
double* val)
const { *val = as_double(); }
void get(std::string* val)
const { *val = as_std_string(); }
void get(ConstChars* val)
const { *val = as_string(); }
void get(ConstBytes* val)
const { *val = as_bytes(); }
void get_signed(int32_t* val)
const { *val = as_sint32(); }
void get_signed(int64_t* val)
const { *val = as_sint64(); }
// For enum types.
template <
typename T,
typename =
typename std::enable_if<std::is_enum<T>::value, T>::type>
void get(T* val)
const {
*val =
static_cast<T>(as_int32());
}
// Serializes the field back into a proto-encoded byte stream and appends it
// to |dst|. |dst| is resized accordingly.
void SerializeAndAppendTo(std::string* dst)
const;
// Serializes the field back into a proto-encoded byte stream and appends it
// to |dst|. |dst| is resized accordingly.
void SerializeAndAppendTo(std::vector<uint8_t>* dst)
const;
static constexpr uint32_t kMaxId = (1 << 24) - 1;
// See id_ : 24 below.
private:
template <
typename Container>
void SerializeAndAppendToInternal(Container* dst)
const;
// Fields are deliberately not initialized to keep the class trivially
// constructible. It makes a large perf difference for ProtoDecoder.
uint64_t int_value_;
// In kLengthDelimited this contains the data() addr.
uint32_t size_;
// Only valid when when type == kLengthDelimited.
// Note: MSVC and clang-cl require bit-fields to be of the same type, hence
// the `: 8` below rather than uint8_t.
uint32_t id_ : 24;
// Proto field ordinal.
uint32_t type_ : 8;
// proto_utils::ProtoWireType.
};
// The Field struct is used in a lot of perf-sensitive contexts.
static_assert(
sizeof(Field) == 16,
"Field struct too big");
}
// namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
// gen_amalgamated begin header: include/perfetto/tracing/core/forward_decls.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_CORE_FORWARD_DECLS_H_
#define INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
// Forward declares classes that are generated at build-time from protos.
// First of all, why are we forward declaring at all?
// 1. Chromium diverges from the Google style guide on this, because forward
// declarations typically make build times faster, and that's a desirable
// property for a large and complex codebase.
// 2. Adding #include to build-time-generated headers from headers typically
// creates subtle build errors that are hard to spot in GN. This is because
// once a standard header (say foo.h) has an #include "protos/foo.gen.h",
// the build target that depends on foo.h needs to depend on the genrule
// that generates foo.gen.h. This is achievable using public_deps in GN but
// is not testable / enforceable, hence too easy to get wrong.
// Historically the classes below used to be generated from the corresponding
// .proto(s) at CL *check-in* time (!= build time) in the ::perfetto namespace.
// Nowadays we have code everywhere that assume the right class is
// ::perfetto::TraceConfig or the like. Back then other headers could just
// forward declared ::perfetto::TraceConfig. These days, the real class is
// ::perfetto::protos::gen::TraceConfig and core/trace_config.h aliases that as
// using ::perfetto::TraceConfig = ::perfetto::protos::gen::TraceConfig.
// In C++ one cannot forward declare a type alias (but only the aliased type).
// Hence this header, which should be used every time one wants to forward
// declare classes like TraceConfig.
// The overall plan is that, when one of the classes below is needed:
// The .h file includes this file.
// The .cc file includes perfetto/tracing/core/trace_config.h (or equiv). That
// header will pull the full declaration from trace_config.gen.h and will also
// setup the alias in the ::perfetto namespace.
namespace perfetto {
namespace protos {
namespace gen {
class ChromeConfig;
class CommitDataRequest;
class DataSourceConfig;
class DataSourceDescriptor;
class ObservableEvents;
class TraceConfig;
class TraceStats;
class TracingServiceCapabilities;
class TracingServiceState;
class SyncClockRequest;
class SyncClockResponse;
}
// namespace gen
}
// namespace protos
using ChromeConfig = ::perfetto::protos::gen::ChromeConfig;
using CommitDataRequest = ::perfetto::protos::gen::CommitDataRequest;
using DataSourceConfig = ::perfetto::protos::gen::DataSourceConfig;
using DataSourceDescriptor = ::perfetto::protos::gen::DataSourceDescriptor;
using ObservableEvents = ::perfetto::protos::gen::ObservableEvents;
using TraceConfig = ::perfetto::protos::gen::TraceConfig;
using TraceStats = ::perfetto::protos::gen::TraceStats;
using TracingServiceCapabilities =
::perfetto::protos::gen::TracingServiceCapabilities;
using TracingServiceState = ::perfetto::protos::gen::TracingServiceState;
using SyncClockRequest = ::perfetto::protos::gen::SyncClockRequest;
using SyncClockResponse = ::perfetto::protos::gen::SyncClockResponse;
}
// namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
// gen_amalgamated begin header: include/perfetto/tracing/internal/basic_types.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_INTERNAL_BASIC_TYPES_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
#include <stddef.h>
#include <stdint.h>
namespace perfetto {
namespace internal {
// A static_assert in tracing_muxer_impl.cc guarantees that this stays in sync
// with the definition in tracing/core/basic_types.h
using BufferId = uint16_t;
// This is an id of a backend in the TracingMuxer::producer_backends_ list.
// Backends are only added and never removed.
using TracingBackendId = size_t;
// Max numbers of data sources that can be registered in a process.
constexpr size_t kMaxDataSources = 32;
// Max instances for each data source type. This typically matches the
// "max number of concurrent tracing sessions". However remember that a data
// source can be instantiated more than once within one tracing session by
// creating two entries for it in the trace config.
constexpr size_t kMaxDataSourceInstances = 8;
}
// namespace internal
}
// namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
// gen_amalgamated begin header: include/perfetto/tracing/internal/data_source_internal.h
// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_config.h
// gen_amalgamated begin header: gen/protos/perfetto/config/data_source_config.gen.h
// gen_amalgamated begin header: include/perfetto/protozero/cpp_message_obj.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_CPP_MESSAGE_OBJ_H_
#define INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
#include <stdint.h>
#include <string>
#include <vector>
// gen_amalgamated expanded: #include "perfetto/base/export.h"
namespace protozero {
// Base class for generated .gen.h classes, which are full C++ objects that
// support both ser and deserialization (but are not zero-copy).
// This is only used by the "cpp" targets not the "pbzero" ones.
class PERFETTO_EXPORT_COMPONENT CppMessageObj {
public:
virtual ~CppMessageObj();
virtual std::string SerializeAsString()
const = 0;
virtual std::vector<uint8_t> SerializeAsArray()
const = 0;
virtual bool ParseFromArray(
const void*, size_t) = 0;
bool ParseFromString(
const std::string& str) {
return ParseFromArray(str.data(), str.size());
}
};
}
// namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
// gen_amalgamated begin header: include/perfetto/protozero/copyable_ptr.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_COPYABLE_PTR_H_
#define INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
#include <memory>
#include <utility>
namespace protozero {
// This class is essentially a std::vector<T> of fixed size = 1.
// It's a pointer wrapper with deep copying and deep equality comparison.
// At all effects this wrapper behaves like the underlying T, with the exception
// of the heap indirection.
// Conversely to a std::unique_ptr, the pointer will be always valid, never
// null. The problem it solves is the following: when generating C++ classes
// from proto files, we want to keep each header hermetic (i.e. not #include
// headers of dependent types). As such we can't directly instantiate T
// field members but we can instead rely on pointers, so only the .cc file needs
// to see the actual definition of T. If the generated classes were move-only we
// could just use a unique_ptr there. But they aren't, hence this wrapper.
// Converesely to unique_ptr, this wrapper:
// - Default constructs the T instance in its constructor.
// - Implements deep comparison in operator== instead of pointer comparison.
template <
typename T>
class CopyablePtr {
public:
CopyablePtr() : ptr_(
new T()) {}
~CopyablePtr() =
default;
// Copy operators.
CopyablePtr(
const CopyablePtr& other) : ptr_(
new T(*other.ptr_)) {}
CopyablePtr&
operator=(
const CopyablePtr& other) {
*ptr_ = *other.ptr_;
return *
this;
}
// Move operators.
CopyablePtr(CopyablePtr&& other) noexcept : ptr_(std::move(other.ptr_)) {
other.ptr_.reset(
new T());
}
CopyablePtr&
operator=(CopyablePtr&& other) {
ptr_ = std::move(other.ptr_);
other.ptr_.reset(
new T());
return *
this;
}
T* get() {
return ptr_.get(); }
const T* get()
const {
return ptr_.get(); }
T* operator->() {
return ptr_.get(); }
const T* operator->()
const {
return ptr_.get(); }
T&
operator*() {
return *ptr_; }
const T&
operator*()
const {
return *ptr_; }
friend bool operator==(
const CopyablePtr& lhs,
const CopyablePtr& rhs) {
return *lhs == *rhs;
}
friend bool operator!=(
const CopyablePtr& lhs,
const CopyablePtr& rhs) {
// In theory the underlying type might have a special operator!=
// implementation which is not just !(x == y). Respect that.
return *lhs != *rhs;
}
private:
std::unique_ptr<T> ptr_;
};
}
// namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
#include <stdint.h>
#include <bitset>
#include <vector>
#include <string>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
namespace perfetto {
namespace protos {
namespace gen {
class DataSourceConfig;
class TestConfig;
class TestConfig_DummyFields;
class InterceptorConfig;
class ConsoleConfig;
class ChromeConfig;
class SystemInfoConfig;
enum DataSourceConfig_SessionInitiator :
int;
enum ConsoleConfig_Output :
int;
enum ChromeConfig_ClientPriority :
int;
}
// namespace perfetto
}
// namespace protos
}
// namespace gen
namespace protozero {
class Message;
}
// namespace protozero
namespace perfetto {
namespace protos {
namespace gen {
enum DataSourceConfig_SessionInitiator :
int {
DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED = 0,
DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
};
class PERFETTO_EXPORT_COMPONENT DataSourceConfig :
public ::protozero::CppMessageObj {
public:
using SessionInitiator = DataSourceConfig_SessionInitiator;
static constexpr
auto SESSION_INITIATOR_UNSPECIFIED = DataSourceConfig_SessionInitiat
or_SESSION_INITIATOR_UNSPECIFIED;
static constexpr auto SESSION_INITIATOR_TRUSTED_SYSTEM = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
static constexpr auto SessionInitiator_MIN = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
static constexpr auto SessionInitiator_MAX = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
enum FieldNumbers {
kNameFieldNumber = 1,
kTargetBufferFieldNumber = 2,
kTraceDurationMsFieldNumber = 3,
kPreferSuspendClockForDurationFieldNumber = 122,
kStopTimeoutMsFieldNumber = 7,
kEnableExtraGuardrailsFieldNumber = 6,
kSessionInitiatorFieldNumber = 8,
kTracingSessionIdFieldNumber = 4,
kFtraceConfigFieldNumber = 100,
kInodeFileConfigFieldNumber = 102,
kProcessStatsConfigFieldNumber = 103,
kSysStatsConfigFieldNumber = 104,
kHeapprofdConfigFieldNumber = 105,
kJavaHprofConfigFieldNumber = 110,
kAndroidPowerConfigFieldNumber = 106,
kAndroidLogConfigFieldNumber = 107,
kGpuCounterConfigFieldNumber = 108,
kAndroidGameInterventionListConfigFieldNumber = 116,
kPackagesListConfigFieldNumber = 109,
kPerfEventConfigFieldNumber = 111,
kVulkanMemoryConfigFieldNumber = 112,
kTrackEventConfigFieldNumber = 113,
kAndroidPolledStateConfigFieldNumber = 114,
kAndroidSystemPropertyConfigFieldNumber = 118,
kStatsdTracingConfigFieldNumber = 117,
kSystemInfoConfigFieldNumber = 119,
kChromeConfigFieldNumber = 101,
kV8ConfigFieldNumber = 127,
kInterceptorConfigFieldNumber = 115,
kNetworkPacketTraceConfigFieldNumber = 120,
kSurfaceflingerLayersConfigFieldNumber = 121,
kSurfaceflingerTransactionsConfigFieldNumber = 123,
kAndroidSdkSyspropGuardConfigFieldNumber = 124,
kEtwConfigFieldNumber = 125,
kProtologConfigFieldNumber = 126,
kAndroidInputEventConfigFieldNumber = 128,
kPixelModemConfigFieldNumber = 129,
kWindowmanagerConfigFieldNumber = 130,
kChromiumSystemMetricsFieldNumber = 131,
kLegacyConfigFieldNumber = 1000,
kForTestingFieldNumber = 1001,
};
DataSourceConfig();
~DataSourceConfig() override;
DataSourceConfig(DataSourceConfig&&) noexcept;
DataSourceConfig& operator=(DataSourceConfig&&);
DataSourceConfig(const DataSourceConfig&);
DataSourceConfig& operator=(const DataSourceConfig&);
bool operator==(const DataSourceConfig&) const;
bool operator!=(const DataSourceConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_name() const { return _has_field_[1]; }
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
bool has_target_buffer() const { return _has_field_[2]; }
uint32_t target_buffer() const { return target_buffer_; }
void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
bool has_trace_duration_ms() const { return _has_field_[3]; }
uint32_t trace_duration_ms() const { return trace_duration_ms_; }
void set_trace_duration_ms(uint32_t value) { trace_duration_ms_ = value; _has_field_.set(3); }
bool has_prefer_suspend_clock_for_duration() const { return _has_field_[122]; }
bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(122); }
bool has_stop_timeout_ms() const { return _has_field_[7]; }
uint32_t stop_timeout_ms() const { return stop_timeout_ms_; }
void set_stop_timeout_ms(uint32_t value) { stop_timeout_ms_ = value; _has_field_.set(7); }
bool has_enable_extra_guardrails() const { return _has_field_[6]; }
bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(6); }
bool has_session_initiator() const { return _has_field_[8]; }
DataSourceConfig_SessionInitiator session_initiator() const { return session_initiator_; }
void set_session_initiator(DataSourceConfig_SessionInitiator value) { session_initiator_ = value; _has_field_.set(8); }
bool has_tracing_session_id() const { return _has_field_[4]; }
uint64_t tracing_session_id() const { return tracing_session_id_; }
void set_tracing_session_id(uint64_t value) { tracing_session_id_ = value; _has_field_.set(4); }
const std::string& ftrace_config_raw() const { return ftrace_config_; }
void set_ftrace_config_raw(const std::string& raw) { ftrace_config_ = raw; _has_field_.set(100); }
const std::string& inode_file_config_raw() const { return inode_file_config_; }
void set_inode_file_config_raw(const std::string& raw) { inode_file_config_ = raw; _has_field_.set(102); }
const std::string& process_stats_config_raw() const { return process_stats_config_; }
void set_process_stats_config_raw(const std::string& raw) { process_stats_config_ = raw; _has_field_.set(103); }
const std::string& sys_stats_config_raw() const { return sys_stats_config_; }
void set_sys_stats_config_raw(const std::string& raw) { sys_stats_config_ = raw; _has_field_.set(104); }
const std::string& heapprofd_config_raw() const { return heapprofd_config_; }
void set_heapprofd_config_raw(const std::string& raw) { heapprofd_config_ = raw; _has_field_.set(105); }
const std::string& java_hprof_config_raw() const { return java_hprof_config_; }
void set_java_hprof_config_raw(const std::string& raw) { java_hprof_config_ = raw; _has_field_.set(110); }
const std::string& android_power_config_raw() const { return android_power_config_; }
void set_android_power_config_raw(const std::string& raw) { android_power_config_ = raw; _has_field_.set(106); }
const std::string& android_log_config_raw() const { return android_log_config_; }
void set_android_log_config_raw(const std::string& raw) { android_log_config_ = raw; _has_field_.set(107); }
const std::string& gpu_counter_config_raw() const { return gpu_counter_config_; }
void set_gpu_counter_config_raw(const std::string& raw) { gpu_counter_config_ = raw; _has_field_.set(108); }
const std::string& android_game_intervention_list_config_raw() const { return android_game_intervention_list_config_; }
void set_android_game_intervention_list_config_raw(const std::string& raw) { android_game_intervention_list_config_ = raw; _has_field_.set(116); }
const std::string& packages_list_config_raw() const { return packages_list_config_; }
void set_packages_list_config_raw(const std::string& raw) { packages_list_config_ = raw; _has_field_.set(109); }
const std::string& perf_event_config_raw() const { return perf_event_config_; }
void set_perf_event_config_raw(const std::string& raw) { perf_event_config_ = raw; _has_field_.set(111); }
const std::string& vulkan_memory_config_raw() const { return vulkan_memory_config_; }
void set_vulkan_memory_config_raw(const std::string& raw) { vulkan_memory_config_ = raw; _has_field_.set(112); }
const std::string& track_event_config_raw() const { return track_event_config_; }
void set_track_event_config_raw(const std::string& raw) { track_event_config_ = raw; _has_field_.set(113); }
const std::string& android_polled_state_config_raw() const { return android_polled_state_config_; }
void set_android_polled_state_config_raw(const std::string& raw) { android_polled_state_config_ = raw; _has_field_.set(114); }
const std::string& android_system_property_config_raw() const { return android_system_property_config_; }
void set_android_system_property_config_raw(const std::string& raw) { android_system_property_config_ = raw; _has_field_.set(118); }
const std::string& statsd_tracing_config_raw() const { return statsd_tracing_config_; }
void set_statsd_tracing_config_raw(const std::string& raw) { statsd_tracing_config_ = raw; _has_field_.set(117); }
bool has_system_info_config() const { return _has_field_[119]; }
const SystemInfoConfig& system_info_config() const { return *system_info_config_; }
SystemInfoConfig* mutable_system_info_config() { _has_field_.set(119); return system_info_config_.get(); }
bool has_chrome_config() const { return _has_field_[101]; }
const ChromeConfig& chrome_config() const { return *chrome_config_; }
ChromeConfig* mutable_chrome_config() { _has_field_.set(101); return chrome_config_.get(); }
const std::string& v8_config_raw() const { return v8_config_; }
void set_v8_config_raw(const std::string& raw) { v8_config_ = raw; _has_field_.set(127); }
bool has_interceptor_config() const { return _has_field_[115]; }
const InterceptorConfig& interceptor_config() const { return *interceptor_config_; }
InterceptorConfig* mutable_interceptor_config() { _has_field_.set(115); return interceptor_config_.get(); }
const std::string& network_packet_trace_config_raw() const { return network_packet_trace_config_; }
void set_network_packet_trace_config_raw(const std::string& raw) { network_packet_trace_config_ = raw; _has_field_.set(120); }
const std::string& surfaceflinger_layers_config_raw() const { return surfaceflinger_layers_config_; }
void set_surfaceflinger_layers_config_raw(const std::string& raw) { surfaceflinger_layers_config_ = raw; _has_field_.set(121); }
const std::string& surfaceflinger_transactions_config_raw() const { return surfaceflinger_transactions_config_; }
void set_surfaceflinger_transactions_config_raw(const std::string& raw) { surfaceflinger_transactions_config_ = raw; _has_field_.set(123); }
const std::string& android_sdk_sysprop_guard_config_raw() const { return android_sdk_sysprop_guard_config_; }
void set_android_sdk_sysprop_guard_config_raw(const std::string& raw) { android_sdk_sysprop_guard_config_ = raw; _has_field_.set(124); }
const std::string& etw_config_raw() const { return etw_config_; }
void set_etw_config_raw(const std::string& raw) { etw_config_ = raw; _has_field_.set(125); }
const std::string& protolog_config_raw() const { return protolog_config_; }
void set_protolog_config_raw(const std::string& raw) { protolog_config_ = raw; _has_field_.set(126); }
const std::string& android_input_event_config_raw() const { return android_input_event_config_; }
void set_android_input_event_config_raw(const std::string& raw) { android_input_event_config_ = raw; _has_field_.set(128); }
const std::string& pixel_modem_config_raw() const { return pixel_modem_config_; }
void set_pixel_modem_config_raw(const std::string& raw) { pixel_modem_config_ = raw; _has_field_.set(129); }
const std::string& windowmanager_config_raw() const { return windowmanager_config_; }
void set_windowmanager_config_raw(const std::string& raw) { windowmanager_config_ = raw; _has_field_.set(130); }
const std::string& chromium_system_metrics_raw() const { return chromium_system_metrics_; }
void set_chromium_system_metrics_raw(const std::string& raw) { chromium_system_metrics_ = raw; _has_field_.set(131); }
bool has_legacy_config() const { return _has_field_[1000]; }
const std::string& legacy_config() const { return legacy_config_; }
void set_legacy_config(const std::string& value) { legacy_config_ = value; _has_field_.set(1000); }
bool has_for_testing() const { return _has_field_[1001]; }
const TestConfig& for_testing() const { return *for_testing_; }
TestConfig* mutable_for_testing() { _has_field_.set(1001); return for_testing_.get(); }
private:
std::string name_{};
uint32_t target_buffer_{};
uint32_t trace_duration_ms_{};
bool prefer_suspend_clock_for_duration_{};
uint32_t stop_timeout_ms_{};
bool enable_extra_guardrails_{};
DataSourceConfig_SessionInitiator session_initiator_{};
uint64_t tracing_session_id_{};
std::string ftrace_config_; // [lazy=true]
std::string inode_file_config_; // [lazy=true]
std::string process_stats_config_; // [lazy=true]
std::string sys_stats_config_; // [lazy=true]
std::string heapprofd_config_; // [lazy=true]
std::string java_hprof_config_; // [lazy=true]
std::string android_power_config_; // [lazy=true]
std::string android_log_config_; // [lazy=true]
std::string gpu_counter_config_; // [lazy=true]
std::string android_game_intervention_list_config_; // [lazy=true]
std::string packages_list_config_; // [lazy=true]
std::string perf_event_config_; // [lazy=true]
std::string vulkan_memory_config_; // [lazy=true]
std::string track_event_config_; // [lazy=true]
std::string android_polled_state_config_; // [lazy=true]
std::string android_system_property_config_; // [lazy=true]
std::string statsd_tracing_config_; // [lazy=true]
::protozero::CopyablePtr<SystemInfoConfig> system_info_config_;
::protozero::CopyablePtr<ChromeConfig> chrome_config_;
std::string v8_config_; // [lazy=true]
::protozero::CopyablePtr<InterceptorConfig> interceptor_config_;
std::string network_packet_trace_config_; // [lazy=true]
std::string surfaceflinger_layers_config_; // [lazy=true]
std::string surfaceflinger_transactions_config_; // [lazy=true]
std::string android_sdk_sysprop_guard_config_; // [lazy=true]
std::string etw_config_; // [lazy=true]
std::string protolog_config_; // [lazy=true]
std::string android_input_event_config_; // [lazy=true]
std::string pixel_modem_config_; // [lazy=true]
std::string windowmanager_config_; // [lazy=true]
std::string chromium_system_metrics_; // [lazy=true]
std::string legacy_config_{};
::protozero::CopyablePtr<TestConfig> for_testing_;
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<1002> _has_field_{};
};
} // namespace perfetto
} // namespace protos
} // namespace gen
#endif // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_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_TRACING_CORE_DATA_SOURCE_CONFIG_H_
#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
#endif // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
// gen_amalgamated begin header: include/perfetto/tracing/trace_writer_base.h
// gen_amalgamated begin header: include/perfetto/protozero/message_handle.h
// gen_amalgamated begin header: include/perfetto/protozero/message.h
// gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_writer.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_SCATTERED_STREAM_WRITER_H_
#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <algorithm>
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
namespace protozero {
// This class deals with the following problem: append-only proto messages want
// to write a stream of bytes, without caring about the implementation of the
// underlying buffer (which concretely will be either the trace ring buffer
// or a heap-allocated buffer). The main deal is: proto messages don't know in
// advance what their size will be.
// Due to the tracing buffer being split into fixed-size chunks, on some
// occasions, these writes need to be spread over two (or more) non-contiguous
// chunks of memory. Similarly, when the buffer is backed by the heap, we want
// to avoid realloc() calls, as they might cause a full copy of the contents
// of the buffer.
// The purpose of this class is to abstract away the non-contiguous write logic.
// This class knows how to deal with writes as long as they fall in the same
// ContiguousMemoryRange and defers the chunk-chaining logic to the Delegate.
class PERFETTO_EXPORT_COMPONENT ScatteredStreamWriter {
public:
class PERFETTO_EXPORT_COMPONENT Delegate {
public:
static constexpr size_t kPatchSize = 4;
virtual ~Delegate();
// Returns a new chunk for writing.
virtual ContiguousMemoryRange GetNewBuffer() = 0;
// Signals the delegate that the location pointed by `to_patch` (which must
// be in the last chunk returned by GetNewBuffer()), kPatchSize long, needs
// to be updated later (after potentially multiple GetNewBuffer calls).
//
// The caller must write to the returned location later. If the returned
// pointer is nullptr, the caller should not write anything.
//
// The implementation considers the patch ready to apply when the caller
// writes the first byte a value that's different than 0 (the
// implementation periodically checks for this).
virtual uint8_t* AnnotatePatch(uint8_t* patch_addr);
};
explicit ScatteredStreamWriter(Delegate* delegate);
~ScatteredStreamWriter();
inline void WriteByte(uint8_t value) {
if (write_ptr_ >= cur_range_.end)
Extend();
*write_ptr_++ = value;
}
// Assumes that the caller checked that there is enough headroom.
// TODO(primiano): perf optimization, this is a tracing hot path. The
// compiler can make strong optimization on std::copy if the size arg is a
// constexpr. Make a templated variant of this for fixed-size writes.
// TODO(primiano): restrict / noalias might also help.
inline void WriteBytesUnsafe(const uint8_t* src, size_t size) {
uint8_t* const end = write_ptr_ + size;
assert(end <= cur_range_.end);
std::copy(src, src + size, write_ptr_);
write_ptr_ = end;
}
inline void WriteBytes(const uint8_t* src,
size_t size) PERFETTO_NO_SANITIZE_UNDEFINED {
// If the stream writer hasn't been initialized, constructing the end
// pointer below invokes undefined behavior because `write_ptr_` is null.
// Since this function is on the hot path, we suppress the warning instead
// of adding a conditional branch.
uint8_t* const end = write_ptr_ + size;
if (PERFETTO_LIKELY(end <= cur_range_.end))
return WriteBytesUnsafe(src, size);
WriteBytesSlowPath(src, size);
}
void WriteBytesSlowPath(const uint8_t* src, size_t size);
// Reserves a fixed amount of bytes to be backfilled later. The reserved range
// is guaranteed to be contiguous and not span across chunks. |size| has to be
// <= than the size of a new buffer returned by the Delegate::GetNewBuffer().
uint8_t* ReserveBytes(size_t size);
// Fast (but unsafe) version of the above. The caller must have previously
// checked that there are at least |size| contiguous bytes available.
// Returns only the start pointer of the reservation.
uint8_t* ReserveBytesUnsafe(size_t size) {
uint8_t* begin = write_ptr_;
write_ptr_ += size;
assert(write_ptr_ <= cur_range_.end);
return begin;
}
// Shifts the previously written `size` bytes backwards in memory by `offset`
// bytes, moving the write pointer back accordingly. The shifted result must
// still be fully contained by the current range.
void Rewind(size_t size, size_t offset) {
uint8_t* src = write_ptr_ - size;
uint8_t* dst = src - offset;
PERFETTO_DCHECK(src >= cur_range_.begin);
PERFETTO_DCHECK(src + size <= cur_range_.end);
PERFETTO_DCHECK(dst >= cur_range_.begin);
PERFETTO_DCHECK(dst + size <= cur_range_.end);
memmove(dst, src, size);
write_ptr_ -= offset;
}
// Resets the buffer boundaries and the write pointer to the given |range|.
// Subsequent WriteByte(s) will write into |range|.
void Reset(ContiguousMemoryRange range);
// Commits the current chunk and gets a new chunk from the delegate.
void Extend();
// Number of contiguous free bytes in |cur_range_| that can be written without
// requesting a new buffer.
size_t bytes_available() const {
return static_cast<size_t>(cur_range_.end - write_ptr_);
}
ContiguousMemoryRange cur_range() const { return cur_range_; }
uint8_t* write_ptr() const { return write_ptr_; }
void set_write_ptr(uint8_t* write_ptr) {
assert(cur_range_.begin <= write_ptr && write_ptr <= cur_range_.end);
write_ptr_ = write_ptr;
}
uint64_t written() const {
return written_previously_ +
static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
}
uint64_t written_previously() const { return written_previously_; }
uint8_t* AnnotatePatch(uint8_t* patch_addr) {
return delegate_->AnnotatePatch(patch_addr);
}
private:
ScatteredStreamWriter(const ScatteredStreamWriter&) = delete;
ScatteredStreamWriter& operator=(const ScatteredStreamWriter&) = delete;
Delegate* const delegate_;
ContiguousMemoryRange cur_range_;
uint8_t* write_ptr_;
uint64_t written_previously_ = 0;
};
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_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_MESSAGE_H_
#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <string>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// 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"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
namespace perfetto {
namespace shm_fuzz {
class FakeProducer;
} // namespace shm_fuzz
} // namespace perfetto
namespace protozero {
class MessageArena;
class MessageHandleBase;
// Base class extended by the proto C++ stubs generated by the ProtoZero
// compiler. This class provides the minimal runtime required to support
// append-only operations and is designed for performance. None of the methods
// require any dynamic memory allocation, unless more than 16 nested messages
// are created via BeginNestedMessage() calls.
class PERFETTO_EXPORT_COMPONENT Message {
public:
friend class MessageHandleBase;
// The ctor is deliberately a no-op to avoid forwarding args from all
// subclasses. The real initialization is performed by Reset().
// Nested messages are allocated via placement new by MessageArena and
// implictly destroyed when the RootMessage's arena goes away. This is
// fine as long as all the fields are PODs, which is checked by the
// static_assert()s in the Reset() method.
Message() = default;
// Clears up the state, allowing the message to be reused as a fresh one.
void Reset(ScatteredStreamWriter*, MessageArena*);
// Commits all the changes to the buffer (backfills the size field of this and
// all nested messages) and seals the message. Returns the size of the message
// (and all nested sub-messages), without taking into account any chunking.
// Finalize is idempotent and can be called several times w/o side effects.
// Short messages may be compacted in memory into the size field, since their
// size can be represented with fewer than
// proto_utils::kMessageLengthFieldSize bytes.
uint32_t Finalize();
// Optional. If is_valid() == true, the corresponding memory region (its
// length == proto_utils::kMessageLengthFieldSize) is backfilled with the size
// of this message. This is the mechanism used by messages to backfill their
// corresponding size field in the parent message. In most cases this is only
// used for nested messages and the ScatteredStreamWriter::Delegate (e.g.
// TraceWriterImpl), takes case of the outer message.
uint8_t* size_field() const { return size_field_; }
void set_size_field(uint8_t* size_field) { size_field_ = size_field; }
Message* nested_message() { return nested_message_; }
bool is_finalized() const {
return message_state_ != MessageState::kNotFinalized;
}
#if PERFETTO_DCHECK_IS_ON()
void set_handle(MessageHandleBase* handle) { handle_ = handle; }
#endif
// Proto types: uint64, uint32, int64, int32, bool, enum.
template <typename T>
void AppendVarInt(uint32_t field_id, T value) {
if (nested_message_)
EndNestedMessage();
uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
uint8_t* pos = buffer;
pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
// WriteVarInt encodes signed values in two's complement form.
pos = proto_utils::WriteVarInt(value, pos);
WriteToStream(buffer, pos);
}
// Proto types: sint64, sint32.
template <typename T>
void AppendSignedVarInt(uint32_t field_id, T value) {
AppendVarInt(field_id, proto_utils::ZigZagEncode(value));
}
// Proto types: bool, enum (small).
// Faster version of AppendVarInt for tiny numbers.
void AppendTinyVarInt(uint32_t field_id, int32_t value) {
PERFETTO_DCHECK(0 <= value && value < 0x80);
if (nested_message_)
EndNestedMessage();
uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
uint8_t* pos = buffer;
// MakeTagVarInt gets super optimized here for constexpr.
pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
*pos++ = static_cast<uint8_t>(value);
WriteToStream(buffer, pos);
}
// Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
template <typename T>
void AppendFixed(uint32_t field_id, T value) {
if (nested_message_)
EndNestedMessage();
uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
uint8_t* pos = buffer;
pos = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<T>(field_id), pos);
memcpy(pos, &value, sizeof(T));
pos += sizeof(T);
// TODO: Optimize memcpy performance, see http://crbug.com/624311 .
WriteToStream(buffer, pos);
}
void AppendString(uint32_t field_id, const char* str);
void AppendString(uint32_t field_id, const std::string& str) {
AppendBytes(field_id, str.data(), str.size());
}
void AppendBytes(uint32_t field_id, const void* value, size_t size);
// Append raw bytes for a field, using the supplied |ranges| to
// copy from |num_ranges| individual buffers.
size_t AppendScatteredBytes(uint32_t field_id,
ContiguousMemoryRange* ranges,
size_t num_ranges);
// Begins a nested message. The returned object is owned by the MessageArena
// of the root message. The nested message ends either when Finalize() is
// called or when any other Append* method is called in the parent class.
// The template argument T is supposed to be a stub class auto generated from
// a .proto, hence a subclass of Message.
template <class T>
T* BeginNestedMessage(uint32_t field_id) {
// This is to prevent subclasses (which should be autogenerated, though), to
// introduce extra state fields (which wouldn't be initialized by Reset()).
static_assert(std::is_base_of<Message, T>::value,
"T must be a subclass of Message");
static_assert(sizeof(T) == sizeof(Message),
"Message subclasses cannot introduce extra state.");
return static_cast<T*>(BeginNestedMessageInternal(field_id));
}
// Gives read-only access to the underlying stream_writer. This is used only
// by few internals to query the state of the underlying buffer. It is almost
// always a bad idea to poke at the stream_writer() internals.
const ScatteredStreamWriter* stream_writer() const { return stream_writer_; }
// Appends some raw bytes to the message. The use-case for this is preserving
// unknown fields in the decode -> re-encode path of xxx.gen.cc classes
// generated by the cppgen_plugin.cc.
// The caller needs to guarantee that the appended data is properly
// proto-encoded and each field has a proto preamble.
void AppendRawProtoBytes(const void* data, size_t size) {
if (nested_message_)
EndNestedMessage();
const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
WriteToStream(src, src + size);
}
private:
Message(const Message&) = delete;
Message& operator=(const Message&) = delete;
Message* BeginNestedMessageInternal(uint32_t field_id);
// Called by Finalize and Append* methods.
void EndNestedMessage();
void WriteToStream(const uint8_t* src_begin, const uint8_t* src_end) {
PERFETTO_DCHECK(!is_finalized());
PERFETTO_DCHECK(src_begin <= src_end);
const uint32_t size = static_cast<uint32_t>(src_end - src_begin);
stream_writer_->WriteBytes(src_begin, size);
size_ += size;
}
// Only POD fields are allowed. This class's dtor is never called.
// See the comment on the static_assert in the corresponding .cc file.
// The stream writer interface used for the serialization.
ScatteredStreamWriter* stream_writer_;
// The storage used to allocate nested Message objects.
// This is owned by RootMessage<T>.
MessageArena* arena_;
// Pointer to the last child message created through BeginNestedMessage(), if
// any, nullptr otherwise. There is no need to keep track of more than one
// message per nesting level as the proto-zero API contract mandates that
// nested fields can be filled only in a stacked fashion. In other words,
// nested messages are finalized and sealed when any other field is set in the
// parent message (or the parent message itself is finalized) and cannot be
// accessed anymore afterwards.
Message* nested_message_;
// [optional] Pointer to a non-aligned pre-reserved var-int slot of
// kMessageLengthFieldSize bytes. When set, the Finalize() method will write
// the size of proto-encoded message in the pointed memory region.
uint8_t* size_field_;
// Keeps track of the size of the current message.
uint32_t size_;
enum class MessageState : uint8_t {
// Message is still being written to.
kNotFinalized,
// Finalized, no more changes to the message are allowed. This is to DCHECK
// attempts of writing to a message which has been Finalize()-d.
kFinalized,
// Finalized, and additionally the message data has been partially or fully
// compacted into the last 3 bytes of `size_field_`. See the comment in
// Finalize().
kFinalizedWithCompaction,
};
MessageState message_state_;
#if PERFETTO_DCHECK_IS_ON()
// Current generation of message. Incremented on Reset.
// Used to detect stale handles.
uint32_t generation_;
MessageHandleBase* handle_;
#endif
};
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_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_MESSAGE_HANDLE_H_
#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
#include <functional>
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
namespace protozero {
class Message;
class PERFETTO_EXPORT_COMPONENT MessageFinalizationListener {
public:
virtual ~MessageFinalizationListener();
virtual void OnMessageFinalized(Message* message) = 0;
};
// MessageHandle allows to decouple the lifetime of a proto message
// from the underlying storage. It gives the following guarantees:
// - The underlying message is finalized (if still alive) if the handle goes
// out of scope.
// - In Debug / DCHECK_ALWAYS_ON builds, the handle becomes null once the
// message is finalized. This is to enforce the append-only API. For instance
// when adding two repeated messages, the addition of the 2nd one forces
// the finalization of the first.
// Think about this as a WeakPtr<Message> which calls
// Message::Finalize() when going out of scope.
class PERFETTO_EXPORT_COMPONENT MessageHandleBase {
public:
~MessageHandleBase() {
if (message_) {
#if PERFETTO_DCHECK_IS_ON()
PERFETTO_DCHECK(generation_ == message_->generation_);
#endif
FinalizeMessage();
}
}
// Move-only type.
MessageHandleBase(MessageHandleBase&& other) noexcept {
Move(std::move(other));
}
MessageHandleBase& operator=(MessageHandleBase&& other) noexcept {
// If the current handle was pointing to a message and is being reset to a
// new one, finalize the old message. However, if the other message is the
// same as the one we point to, don't finalize.
if (message_ && message_ != other.message_)
FinalizeMessage();
Move(std::move(other));
return *this;
}
explicit operator bool() const {
#if PERFETTO_DCHECK_IS_ON()
PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
#endif
return !!message_;
}
void set_finalization_listener(MessageFinalizationListener* listener) {
listener_ = listener;
}
// Returns a (non-owned, it should not be deleted) pointer to the
// ScatteredStreamWriter used to write the message data. The Message becomes
// unusable after this point.
//
// The caller can now write directly, without using protozero::Message.
ScatteredStreamWriter* TakeStreamWriter() {
ScatteredStreamWriter* stream_writer = message_->stream_writer_;
#if PERFETTO_DCHECK_IS_ON()
message_->set_handle(nullptr);
#endif
message_ = nullptr;
listener_ = nullptr;
return stream_writer;
}
protected:
explicit MessageHandleBase(Message* message = nullptr) : message_(message) {
#if PERFETTO_DCHECK_IS_ON()
generation_ = message_ ? message->generation_ : 0;
if (message_)
message_->set_handle(this);
#endif
}
Message* operator->() const {
#if PERFETTO_DCHECK_IS_ON()
PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
#endif
return message_;
}
Message& operator*() const { return *(operator->()); }
private:
friend class Message;
MessageHandleBase(const MessageHandleBase&) = delete;
MessageHandleBase& operator=(const MessageHandleBase&) = delete;
void reset_message() {
// This is called by Message::Finalize().
PERFETTO_DCHECK(message_->is_finalized());
message_ = nullptr;
listener_ = nullptr;
}
void Move(MessageHandleBase&& other) {
message_ = other.message_;
other.message_ = nullptr;
listener_ = other.listener_;
other.listener_ = nullptr;
#if PERFETTO_DCHECK_IS_ON()
if (message_) {
generation_ = message_->generation_;
message_->set_handle(this);
}
#endif
}
void FinalizeMessage() {
// |message_| and |listener_| may be cleared by reset_message() during
// Message::Finalize().
auto* listener = listener_;
auto* message = message_;
message->Finalize();
if (listener)
listener->OnMessageFinalized(message);
}
Message* message_;
MessageFinalizationListener* listener_ = nullptr;
#if PERFETTO_DCHECK_IS_ON()
uint32_t generation_;
#endif
};
template <typename T>
class MessageHandle : public MessageHandleBase {
public:
MessageHandle() : MessageHandle(nullptr) {}
explicit MessageHandle(T* message) : MessageHandleBase(message) {}
explicit operator bool() const { return MessageHandleBase::operator bool(); }
T& operator*() const {
return static_cast<T&>(MessageHandleBase::operator*());
}
T* operator->() const {
return static_cast<T*>(MessageHandleBase::operator->());
}
T* get() const { return static_cast<T*>(MessageHandleBase::operator->()); }
};
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_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_TRACE_WRITER_BASE_H_
#define INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
namespace perfetto {
namespace protos {
namespace pbzero {
class TracePacket;
} // namespace pbzero
} // namespace protos
// This is a single-thread write interface that allows to write protobufs
// directly into the tracing shared buffer without making any copies.
// The idea is that each data source creates one (or more) TraceWriter for each
// thread it wants to write from. Each TraceWriter will get its own dedicated
// chunk and will write into the shared buffer without any locking most of the
// time.
class PERFETTO_EXPORT_COMPONENT TraceWriterBase {
public:
virtual ~TraceWriterBase();
// Creates a new trace packet and returns a handle to a protozero Message that
// will write to it. The message will be finalized either by calling directly
// handle.Finalize() or by letting the handle go out of scope (the message
// should be finalized before a new call to NewTracePacket is made). The
// returned handle can be std::move()'d but cannot be used after either: (i)
// the TraceWriter instance is destroyed, (ii) a subsequence NewTracePacket()
// call is made on the same TraceWriter instance.
//
// The caller can use protozero::MessageHandle::TakeStreamWriter() to write.
//
// The caller must call ->Finalize() on the returned trace packet (the handle
// destructor will take care of that) or explicitly call FinishTracePacket (if
// using TakeStreamWriter) before calling any method on the same TraceWriter
// instance.
//
// The returned packet handle is always valid, but note that, when using
// BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned
// a garbage chunk and any trace data written into it will be lost. For more
// details on buffer size choices: https://perfetto.dev/docs/concepts/buffers.
virtual protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket() = 0;
// Tells the TraceWriterBase that the previous packet started with
// NewTracePacket() is finished.
//
// Calling this is optional: the TraceWriterBase can realize that the previous
// packet is finished when the next NewTracePacket() is called. It is still
// useful, because the next NewTracePacket may not happen for a while.
virtual void FinishTracePacket() = 0;
// Commits the data pending for the current chunk. This can be called
// only if the handle returned by NewTracePacket() has been destroyed (i.e. we
// cannot Flush() while writing a TracePacket).
//
// Note: Flush() also happens implicitly when destroying the TraceWriter.
//
// |callback| is an optional callback. When non-null it will request the
// service to ACK the flush and will be invoked after the service has
// acknowledged it. The callback might be NEVER INVOKED if the service crashes
// or the IPC connection is dropped. The callback should be used only by tests
// and best-effort features (logging).
virtual void Flush(std::function<void()> callback = {}) = 0;
// Bytes written since creation. Not reset when new chunks are acquired.
virtual uint64_t written() const = 0;
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_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_INTERNAL_DATA_SOURCE_INTERNAL_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
#include <stddef.h>
#include <stdint.h>
#include <array>
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
// No perfetto headers (other than tracing/api and protozero) should be here.
// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
namespace perfetto {
class DataSourceBase;
class InterceptorBase;
class TraceWriterBase;
namespace internal {
class TracingTLS;
// This maintains the internal state of a data source instance that is used only
// to implement the tracing mechanics and is not exposed to the API client.
// There is one of these object per DataSource instance (up to
// kMaxDataSourceInstances).
struct DataSourceState {
// This boolean flag determines whether the DataSource::Trace() method should
// do something or be a no-op. This flag doesn't give the full guarantee
// that tracing data will be visible in the trace, it just makes it so that
// the client attemps writing trace data and interacting with the service.
// For instance, when a tracing session ends the service will reject data
// commits that arrive too late even if the producer hasn't received the stop
// IPC message.
// This flag is set right before calling OnStart() and cleared right before
// calling OnStop(), unless using HandleStopAsynchronously() (see comments
// in data_source.h).
// Keep this flag as the first field. This allows the compiler to directly
// dereference the DataSourceState* pointer in the trace fast-path without
// doing extra pointr arithmetic.
std::atomic<bool> trace_lambda_enabled{false};
// The overall TracingMuxerImpl instance id, which gets incremented by
// ResetForTesting.
uint32_t muxer_id_for_testing = 0;
// The central buffer id that all TraceWriter(s) created by this data source
// must target.
BufferId buffer_id = 0;
// The index within TracingMuxerImpl.backends_. Practically it allows to
// lookup the Producer object, and hence the IPC channel, for this data
// source.
TracingBackendId backend_id = 0;
// Each backend may connect to the tracing service multiple times if a
// disconnection occurs. This counter is used to uniquely identify each
// connection so that trace writers don't get reused across connections.
uint32_t backend_connection_id = 0;
// The instance id as assigned by the tracing service. Note that because a
// process can be connected to >1 services, this ID is not globally unique but
// is only unique within the scope of its backend.
// Only the tuple (backend_id, data_source_instance_id) is globally unique.
uint64_t data_source_instance_id = 0;
// Set to a non-0 target buffer reservation ID iff startup tracing is
// currently enabled for this data source.
std::atomic<uint16_t> startup_target_buffer_reservation{0};
// If the data source was originally started for startup tracing, this is set
// to the startup session's ID.
uint64_t startup_session_id = 0;
// The trace config used by this instance. This is used to de-duplicate
// instances for data sources with identical names (e.g., track event).
// We store it as a pointer to be able to free memory after the datasource
// is stopped.
std::unique_ptr<DataSourceConfig> config;
// If this data source is being intercepted (see Interceptor), this field
// contains the non-zero id of a registered interceptor which should receive
// trace packets for this session. Note: interceptor id 1 refers to the first
// element of TracingMuxerImpl::interceptors_ with successive numbers using
// the following slots.
uint32_t interceptor_id = 0;
// This is set to true when the datasource is in the process of async stop.
// The flag is checked by the tracing muxer to avoid calling OnStop for the
// second time.
bool async_stop_in_progress = false;
// Whether this data source instance should call NotifyDataSourceStopped()
// when it's stopped.
bool will_notify_on_stop = false;
// Incremented whenever incremental state should be reset for this instance of
// this data source.
std::atomic<uint32_t> incremental_state_generation{0};
// This lock is not held to implement Trace() and it's used only if the trace
// code wants to access its own data source state.
// This is to prevent that accessing the data source on an arbitrary embedder
// thread races with the internal IPC thread destroying the data source
// because of a end-of-tracing notification from the service.
// This lock is also used to protect access to a possible interceptor for this
// data source session.
std::recursive_mutex lock;
std::unique_ptr<DataSourceBase> data_source;
std::unique_ptr<InterceptorBase> interceptor;
};
// This is to allow lazy-initialization and avoid static initializers and
// at-exit destructors. All the entries are initialized via placement-new when
// DataSource::Register() is called, see TracingMuxerImpl::RegisterDataSource().
struct DataSourceStateStorage {
alignas(DataSourceState) char storage[sizeof(DataSourceState)]{};
};
// Per-DataSource-type global state.
struct DataSourceStaticState {
// System-wide unique id of the data source.
uint64_t id = 0;
// Unique index of the data source, assigned at registration time.
uint32_t index = kMaxDataSources;
// A bitmap that tells about the validity of each |instances| entry. When the
// i-th bit of the bitmap it's set, instances[i] is valid.
std::atomic<uint32_t> valid_instances{};
std::array<DataSourceStateStorage, kMaxDataSourceInstances> instances{};
// The caller must be sure that `n` was a valid instance at some point (either
// through a previous read of `valid_instances` or because the instance lock
// is held).
DataSourceState* GetUnsafe(size_t n) {
return reinterpret_cast<DataSourceState*>(&instances[n]);
}
// Can be used with a cached |valid_instances| bitmap.
DataSourceState* TryGetCached(uint32_t cached_bitmap, size_t n) {
return cached_bitmap & (1 << n) ? GetUnsafe(n) : nullptr;
}
DataSourceState* TryGet(size_t n) {
return TryGetCached(valid_instances.load(std::memory_order_acquire), n);
}
void CompilerAsserts() {
static_assert(sizeof(valid_instances.load()) * 8 >= kMaxDataSourceInstances,
"kMaxDataSourceInstances too high");
}
void ResetForTesting() {
id = 0;
index = kMaxDataSources;
valid_instances.store(0, std::memory_order_release);
instances = {};
}
};
// Per-DataSource-instance thread-local state.
struct DataSourceInstanceThreadLocalState {
void Reset() { *this = DataSourceInstanceThreadLocalState{}; }
std::unique_ptr<TraceWriterBase> trace_writer;
using ObjectWithDeleter = std::unique_ptr<void, void (*)(void*)>;
ObjectWithDeleter incremental_state = {nullptr, [](void*) {}};
ObjectWithDeleter data_source_custom_tls = {nullptr, [](void*) {}};
uint32_t incremental_state_generation = 0;
uint32_t muxer_id_for_testing = 0;
TracingBackendId backend_id = 0;
uint32_t backend_connection_id = 0;
BufferId buffer_id = 0;
uint64_t data_source_instance_id = 0;
bool is_intercepted = false;
uint64_t last_empty_packet_position = 0;
uint16_t startup_target_buffer_reservation = 0;
};
// Per-DataSource-type thread-local state.
struct DataSourceThreadLocalState {
DataSourceStaticState* static_state = nullptr;
// Pointer to the parent tls object that holds us. Used to retrieve the
// generation, which is per-global-TLS and not per data-source.
TracingTLS* root_tls = nullptr;
// One entry per each data source instance.
std::array<DataSourceInstanceThreadLocalState, kMaxDataSourceInstances>
per_instance{};
};
} // namespace internal
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
// gen_amalgamated begin header: include/perfetto/tracing/locked_handle.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_LOCKED_HANDLE_H_
#define INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
#include <mutex>
namespace perfetto {
// This is used for GetDataSourceLocked(), in the (rare) case where the
// tracing code wants to access the state of its data source from the Trace()
// method.
template <typename T>
class LockedHandle {
public:
LockedHandle(std::unique_lock<std::recursive_mutex> lock, T* obj)
: lock_(std::move(lock)), obj_(obj) {}
LockedHandle() = default; // For the invalid case.
LockedHandle(LockedHandle&&) = default;
LockedHandle& operator=(LockedHandle&&) = default;
bool valid() const { return obj_; }
explicit operator bool() const { return valid(); }
T* operator->() {
assert(valid());
return obj_;
}
T& operator*() { return *(this->operator->()); }
private:
std::unique_lock<std::recursive_mutex> lock_;
T* obj_ = nullptr;
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
/*
* Copyright (C) 2020 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_INTERCEPTOR_H_
#define INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
// An interceptor is used to redirect trace packets written by a data source
// into a custom backend instead of the normal Perfetto tracing service. For
// example, the console interceptor prints all trace packets to the console as
// they are generated. Another potential use is exporting trace data to another
// tracing service such as Android ATrace or Windows ETW.
//
// An interceptor is defined by subclassing the perfetto::Interceptor template:
//
// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
// public:
// ~MyInterceptor() override = default;
//
// // This function is called for each intercepted trace packet. |context|
// // contains information about the trace packet as well as other state
// // tracked by the interceptor (e.g., see ThreadLocalState).
// //
// // Intercepted trace data is provided in the form of serialized protobuf
// // bytes, accessed through the |context.packet_data| field.
// //
// // Warning: this function can be called on any thread at any time. See
// // below for how to safely access shared interceptor data from here.
// static void OnTracePacket(InterceptorContext context) {
// perfetto::protos::pbzero::TracePacket::Decoder packet(
// context.packet_data.data, context.packet_data.size);
// // ... Write |packet| to the desired destination ...
// }
// };
//
// An interceptor should be registered before any tracing sessions are started.
// Note that the interceptor also needs to be activated through the trace config
// as shown below.
//
// perfetto::InterceptorDescriptor desc;
// desc.set_name("my_interceptor");
// MyInterceptor::Register(desc);
//
// Finally, an interceptor is enabled through the trace config like this:
//
// perfetto::TraceConfig cfg;
// auto* ds_cfg = cfg.add_data_sources()->mutable_config();
// ds_cfg->set_name("data_source_to_intercept"); // e.g. "track_event"
// ds_cfg->mutable_interceptor_config()->set_name("my_interceptor");
//
// Once an interceptor is enabled, all data from the affected data sources is
// sent to the interceptor instead of the main tracing buffer.
//
// Interceptor state
// =================
//
// Besides the serialized trace packet data, the |OnTracePacket| interceptor
// function can access three other types of state:
//
// 1. Global state: this is no different from a normal static function, but care
// must be taken because |OnTracePacket| can be called concurrently on any
// thread at any time.
//
// 2. Per-data source instance state: since the interceptor class is
// automatically instantiated for each intercepted data source, its fields
// can be used to store per-instance data such as the trace config. This data
// can be maintained through the OnSetup/OnStart/OnStop callbacks:
//
// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
// public:
// void OnSetup(const SetupArgs& args) override {
// enable_foo_ = args.config.interceptor_config().enable_foo();
// }
//
// bool enable_foo_{};
// };
//
// In the interceptor function this data must be accessed through a scoped
// lock for safety:
//
// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
// ...
// static void OnTracePacket(InterceptorContext context) {
// auto my_interceptor = context.GetInterceptorLocked();
// if (my_interceptor) {
// // Access fields of MyInterceptor here.
// if (my_interceptor->enable_foo_) { ... }
// }
// ...
// }
// };
//
// Since accessing this data involves holding a lock, it should be done
// sparingly.
//
// 3. Per-thread/TraceWriter state: many data sources use interning to avoid
// repeating common data in the trace. Since the interning dictionaries are
// typically kept individually for each TraceWriter sequence (i.e., per
// thread), an interceptor can declare a data structure with lifetime
// matching the TraceWriter:
//
// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
// public:
// struct ThreadLocalState
// : public perfetto::InterceptorBase::ThreadLocalState {
// ThreadLocalState(ThreadLocalStateArgs&) override = default;
// ~ThreadLocalState() override = default;
//
// std::map<size_t, std::string> event_names;
// };
// };
//
// This per-thread state can then be accessed and maintained in
// |OnTracePacket| like this:
//
// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
// ...
// static void OnTracePacket(InterceptorContext context) {
// // Updating interned data.
// auto& tls = context.GetThreadLocalState();
// if (parsed_packet.sequence_flags() & perfetto::protos::pbzero::
// TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
// tls.event_names.clear();
// }
// for (const auto& entry : parsed_packet.interned_data().event_names())
// tls.event_names[entry.iid()] = entry.name();
//
// // Looking up interned data.
// if (parsed_packet.has_track_event()) {
// size_t name_iid = parsed_packet.track_event().name_iid();
// const std::string& event_name = tls.event_names[name_iid];
// }
// ...
// }
// };
//
#include <functional>
// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
// gen_amalgamated expanded: #include "perfetto/tracing/locked_handle.h"
namespace {
class MockTracingMuxer;
}
namespace perfetto {
namespace protos {
namespace gen {
class DataSourceConfig;
class InterceptorDescriptor;
} // namespace gen
} // namespace protos
using protos::gen::InterceptorDescriptor;
namespace internal {
class InterceptorTraceWriter;
class InterceptorTraceWriterTest;
class TracingMuxer;
class TracingMuxerFake;
class TracingMuxerImpl;
} // namespace internal
// A virtual base class for interceptors. Users should derive from the templated
// subclass below instead of this one.
class PERFETTO_EXPORT_COMPONENT InterceptorBase {
public:
virtual ~InterceptorBase();
// A virtual base class for thread-local state needed by the interceptor.
// To define your own state, subclass this with the same name in the
// interceptor class. A reference to the state can then be looked up through
// context.GetThreadLocalState() in the trace packet interceptor function.
class PERFETTO_EXPORT_COMPONENT ThreadLocalState {
public:
virtual ~ThreadLocalState();
};
struct SetupArgs {
const DataSourceConfig& config;
};
struct StartArgs {};
struct StopArgs {};
// Called when an intercepted data source is set up. Both the interceptor's
// and the data source's configuration is available in
// |SetupArgs|. Called on an internal Perfetto service thread, but not
// concurrently.
virtual void OnSetup(const SetupArgs&) {}
// Called when an intercepted data source starts. Called on an internal
// Perfetto service thread, but not concurrently.
virtual void OnStart(const StartArgs&) {}
// Called when an intercepted data source stops. Called on an internal
// Perfetto service thread, but not concurrently.
virtual void OnStop(const StopArgs&) {}
private:
friend class internal::InterceptorTraceWriter;
friend class internal::InterceptorTraceWriterTest;
friend class internal::TracingMuxer;
friend class internal::TracingMuxerFake;
friend class internal::TracingMuxerImpl;
friend MockTracingMuxer;
template <class T>
friend class Interceptor;
// Data passed from DataSource::Trace() into the interceptor.
struct TracePacketCallbackArgs {
internal::DataSourceStaticState* static_state;
uint32_t instance_index;
protozero::ConstBytes packet_data;
ThreadLocalState* tls;
};
// These callback functions are defined as stateless to avoid accidentally
// introducing cross-thread data races.
using TLSFactory = std::unique_ptr<ThreadLocalState> (*)(
internal::DataSourceStaticState*,
uint32_t data_source_instance_index);
using TracePacketCallback = void (*)(TracePacketCallbackArgs);
static void RegisterImpl(
const InterceptorDescriptor& descriptor,
std::function<std::unique_ptr<InterceptorBase>()> factory,
InterceptorBase::TLSFactory tls_factory,
InterceptorBase::TracePacketCallback on_trace_packet);
};
// Templated interceptor instantiation. See above for usage.
template <class InterceptorType>
class PERFETTO_EXPORT_COMPONENT Interceptor : public InterceptorBase {
public:
// A context object provided to the ThreadLocalState constructor. Provides
// access to the per-instance interceptor object.
class ThreadLocalStateArgs {
public:
~ThreadLocalStateArgs() = default;
ThreadLocalStateArgs(const ThreadLocalStateArgs&) = delete;
ThreadLocalStateArgs& operator=(const ThreadLocalStateArgs&) = delete;
ThreadLocalStateArgs(ThreadLocalStateArgs&&) noexcept = default;
ThreadLocalStateArgs& operator=(ThreadLocalStateArgs&&) noexcept = default;
// Return a locked reference to the interceptor session. The session object
// will remain valid as long as the returned handle is in scope.
LockedHandle<InterceptorType> GetInterceptorLocked() {
auto* internal_state = static_state_->TryGet(data_source_instance_index_);
if (!internal_state)
return LockedHandle<InterceptorType>();
std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
return LockedHandle<InterceptorType>(
std::move(lock),
static_cast<InterceptorType*>(internal_state->interceptor.get()));
}
private:
friend class Interceptor<InterceptorType>;
friend class InterceptorContext;
friend class TracingMuxerImpl;
ThreadLocalStateArgs(internal::DataSourceStaticState* static_state,
uint32_t data_source_instance_index)
: static_state_(static_state),
data_source_instance_index_(data_source_instance_index) {}
internal::DataSourceStaticState* const static_state_;
const uint32_t data_source_instance_index_;
};
// A context object provided to each call into |OnTracePacket|. Contains the
// intercepted serialized trace packet data.
class InterceptorContext {
public:
InterceptorContext(InterceptorContext&&) noexcept = default;
~InterceptorContext() = default;
// Return a locked reference to the interceptor session. The session object
// will remain valid as long as the returned handle is in scope.
LockedHandle<InterceptorType> GetInterceptorLocked() {
return tls_args_.GetInterceptorLocked();
}
// Return the thread-local state for this interceptor. See
// InterceptorBase::ThreadLocalState.
typename InterceptorType::ThreadLocalState& GetThreadLocalState() {
return static_cast<typename InterceptorType::ThreadLocalState&>(*tls_);
}
// A buffer containing the serialized TracePacket protocol buffer message.
// This memory is only valid during the call to OnTracePacket.
protozero::ConstBytes packet_data;
private:
friend class Interceptor<InterceptorType>;
InterceptorContext(TracePacketCallbackArgs args)
: packet_data(args.packet_data),
tls_args_(args.static_state, args.instance_index),
tls_(args.tls) {}
InterceptorContext(const InterceptorContext&) = delete;
InterceptorContext& operator=(const InterceptorContext&) = delete;
ThreadLocalStateArgs tls_args_;
InterceptorBase::ThreadLocalState* const tls_;
};
// Register the interceptor for use in tracing sessions.
// The optional |constructor_args| will be passed to the interceptor when it
// is constructed.
template <class... Args>
static void Register(const InterceptorDescriptor& descriptor,
const Args&... constructor_args) {
auto factory = [constructor_args...]() {
return std::unique_ptr<InterceptorBase>(
new InterceptorType(constructor_args...));
};
auto tls_factory = [](internal::DataSourceStaticState* static_state,
uint32_t data_source_instance_index) {
// Don't bother allocating TLS state unless the interceptor is actually
// using it.
if (std::is_same<typename InterceptorType::ThreadLocalState,
InterceptorBase::ThreadLocalState>::value) {
return std::unique_ptr<InterceptorBase::ThreadLocalState>(nullptr);
}
ThreadLocalStateArgs args(static_state, data_source_instance_index);
return std::unique_ptr<InterceptorBase::ThreadLocalState>(
new typename InterceptorType::ThreadLocalState(args));
};
auto on_trace_packet = [](TracePacketCallbackArgs args) {
InterceptorType::OnTracePacket(InterceptorContext(std::move(args)));
};
RegisterImpl(descriptor, std::move(factory), std::move(tls_factory),
std::move(on_trace_packet));
}
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
// gen_amalgamated begin header: include/perfetto/tracing/track_event_state_tracker.h
// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.pbzero.h
// gen_amalgamated begin header: include/perfetto/protozero/field_writer.h
/*
* Copyright (C) 2021 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.
*/
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
#define INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
namespace protozero {
namespace internal {
template <proto_utils::ProtoSchemaType proto_schema_type>
struct FieldWriter {
static_assert(proto_schema_type != proto_utils::ProtoSchemaType::kMessage,
"FieldWriter can't be used with nested messages");
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kDouble> {
inline static void Append(Message& message, uint32_t field_id, double value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kFloat> {
inline static void Append(Message& message, uint32_t field_id, float value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kBool> {
inline static void Append(Message& message, uint32_t field_id, bool value) {
message.AppendTinyVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kInt32> {
inline static void Append(Message& message,
uint32_t field_id,
int32_t value) {
message.AppendVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kInt64> {
inline static void Append(Message& message,
uint32_t field_id,
int64_t value) {
message.AppendVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kUint32> {
inline static void Append(Message& message,
uint32_t field_id,
uint32_t value) {
message.AppendVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kUint64> {
inline static void Append(Message& message,
uint32_t field_id,
uint64_t value) {
message.AppendVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kSint32> {
inline static void Append(Message& message,
uint32_t field_id,
int32_t value) {
message.AppendSignedVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kSint64> {
inline static void Append(Message& message,
uint32_t field_id,
int64_t value) {
message.AppendSignedVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kFixed32> {
inline static void Append(Message& message,
uint32_t field_id,
uint32_t value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kFixed64> {
inline static void Append(Message& message,
uint32_t field_id,
uint64_t value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed32> {
inline static void Append(Message& message,
uint32_t field_id,
int32_t value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed64> {
inline static void Append(Message& message,
uint32_t field_id,
int64_t value) {
message.AppendFixed(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kEnum> {
template <typename EnumType>
inline static void Append(Message& message,
uint32_t field_id,
EnumType value) {
message.AppendVarInt(field_id, value);
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kString> {
inline static void Append(Message& message,
uint32_t field_id,
const char* data,
size_t size) {
message.AppendBytes(field_id, data, size);
}
inline static void Append(Message& message,
uint32_t field_id,
const std::string& value) {
message.AppendBytes(field_id, value.data(), value.size());
}
};
template <>
struct FieldWriter<proto_utils::ProtoSchemaType::kBytes> {
inline static void Append(Message& message,
uint32_t field_id,
const uint8_t* data,
size_t size) {
message.AppendBytes(field_id, data, size);
}
inline static void Append(Message& message,
uint32_t field_id,
const std::string& value) {
message.AppendBytes(field_id, value.data(), value.size());
}
};
} // namespace internal
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
// gen_amalgamated begin header: include/perfetto/protozero/packed_repeated_fields.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_PACKED_REPEATED_FIELDS_H_
#define INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
#include <stdint.h>
#include <array>
#include <memory>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
namespace protozero {
// This file contains classes used when encoding packed repeated fields.
// To encode such a field, the caller is first expected to accumulate all of the
// values in one of the following types (depending on the wire type of the
// individual elements), defined below:
// * protozero::PackedVarInt
// * protozero::PackedFixedSizeInt</*element_type=*/ uint32_t>
// Then that buffer is passed to the protozero-generated setters as an argument.
// After calling the setter, the buffer can be destroyed.
//
// An example of encoding a packed field:
// protozero::HeapBuffered<protozero::Message> msg;
// protozero::PackedVarInt buf;
// buf.Append(42);
// buf.Append(-1);
// msg->set_fieldname(buf);
// msg.SerializeAsString();
class PackedBufferBase {
public:
PackedBufferBase() { Reset(); }
// Copy or move is disabled due to pointers to stack addresses.
PackedBufferBase(const PackedBufferBase&) = delete;
PackedBufferBase(PackedBufferBase&&) = delete;
PackedBufferBase& operator=(const PackedBufferBase&) = delete;
PackedBufferBase& operator=(PackedBufferBase&&) = delete;
void Reset();
const uint8_t* data() const { return storage_begin_; }
size_t size() const {
return static_cast<size_t>(write_ptr_ - storage_begin_);
}
protected:
void GrowIfNeeded() {
PERFETTO_DCHECK(write_ptr_ >= storage_begin_ && write_ptr_ <= storage_end_);
if (PERFETTO_UNLIKELY(write_ptr_ + kMaxElementSize > storage_end_)) {
GrowSlowpath();
}
}
void GrowSlowpath();
// max(uint64_t varint encoding, biggest fixed type (uint64)).
static constexpr size_t kMaxElementSize = 10;
// So sizeof(this) == 8k.
static constexpr size_t kOnStackStorageSize = 8192 - 32;
uint8_t* storage_begin_;
uint8_t* storage_end_;
uint8_t* write_ptr_;
std::unique_ptr<uint8_t[]> heap_buf_;
alignas(uint64_t) uint8_t stack_buf_[kOnStackStorageSize];
};
class PackedVarInt : public PackedBufferBase {
public:
template <typename T>
void Append(T value) {
GrowIfNeeded();
write_ptr_ = proto_utils::WriteVarInt(value, write_ptr_);
}
};
template <typename T /* e.g. uint32_t for Fixed32 */>
class PackedFixedSizeInt : public PackedBufferBase {
public:
void Append(T value) {
static_assert(sizeof(T) == 4 || sizeof(T) == 8,
"PackedFixedSizeInt should be used only with 32/64-bit ints");
static_assert(sizeof(T) <= kMaxElementSize,
"kMaxElementSize needs to be updated");
GrowIfNeeded();
PERFETTO_DCHECK(reinterpret_cast<size_t>(write_ptr_) % alignof(T) == 0);
memcpy(reinterpret_cast<T*>(write_ptr_), &value, sizeof(T));
write_ptr_ += sizeof(T);
}
};
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
// gen_amalgamated begin header: include/perfetto/protozero/proto_decoder.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_PROTOZERO_PROTO_DECODER_H_
#define INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
#include <stdint.h>
#include <array>
#include <memory>
#include <vector>
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
namespace protozero {
// A generic protobuf decoder. Doesn't require any knowledge about the proto
// schema. It tokenizes fields, retrieves their ID and type and exposes
// accessors to retrieve its values.
// It does NOT recurse in nested submessages, instead it just computes their
// boundaries, recursion is left to the caller.
// This class is designed to be used in perf-sensitive contexts. It does not
// allocate and does not perform any proto semantic checks (e.g. repeated /
// required / optional). It's supposedly safe wrt out-of-bounds memory accesses
// (see proto_decoder_fuzzer.cc).
// This class serves also as a building block for TypedProtoDecoder, used when
// the schema is known at compile time.
class PERFETTO_EXPORT_COMPONENT ProtoDecoder {
public:
// Creates a ProtoDecoder using the given |buffer| with size |length| bytes.
ProtoDecoder(const void* buffer, size_t length)
: begin_(reinterpret_cast<const uint8_t*>(buffer)),
end_(begin_ + length),
read_ptr_(begin_) {}
ProtoDecoder(const std::string& str) : ProtoDecoder(str.data(), str.size()) {}
ProtoDecoder(const ConstBytes& cb) : ProtoDecoder(cb.data, cb.size) {}
// Reads the next field from the buffer and advances the read cursor. If a
// full field cannot be read, the returned Field will be invalid (i.e.
// field.valid() == false).
Field ReadField();
// Finds the first field with the given id. Doesn't affect the read cursor.
Field FindField(uint32_t field_id);
// Resets the read cursor to the start of the buffer.
void Reset() { read_ptr_ = begin_; }
// Resets the read cursor to the given position (must be within the buffer).
void Reset(const uint8_t* pos) {
PERFETTO_DCHECK(pos >= begin_ && pos < end_);
read_ptr_ = pos;
}
// Returns the position of read cursor, relative to the start of the buffer.
size_t read_offset() const { return static_cast<size_t>(read_ptr_ - begin_); }
size_t bytes_left() const {
PERFETTO_DCHECK(read_ptr_ <= end_);
return static_cast<size_t>(end_ - read_ptr_);
}
const uint8_t* begin() const { return begin_; }
const uint8_t* end() const { return end_; }
protected:
const uint8_t* const begin_;
const uint8_t* const end_;
const uint8_t* read_ptr_ = nullptr;
};
// An iterator-like class used to iterate through repeated fields. Used by
// TypedProtoDecoder. The iteration sequence is a bit counter-intuitive due to
// the fact that fields_[field_id] holds the *last* value of the field, not the
// first, but the remaining storage holds repeated fields in FIFO order.
// Assume that we push the 10,11,12 into a repeated field with ID=1.
//
// Decoder memory layout: [ fields storage ] [ repeated fields storage ]
// 1st iteration: 10
// 2nd iteration: 11 10
// 3rd iteration: 12 10 11
//
// We start the iteration @ fields_[num_fields], which is the start of the
// repeated fields storage, proceed until the end and lastly jump @ fields_[id].
template <typename T>
class RepeatedFieldIterator {
public:
RepeatedFieldIterator(uint32_t field_id,
const Field* begin,
const Field* end,
const Field* last)
: field_id_(field_id), iter_(begin), end_(end), last_(last) {
FindNextMatchingId();
}
// Constructs an invalid iterator.
RepeatedFieldIterator()
: field_id_(0u), iter_(nullptr), end_(nullptr), last_(nullptr) {}
explicit operator bool() const { return iter_ != end_; }
const Field& field() const { return *iter_; }
T operator*() const {
T val{};
iter_->get(&val);
return val;
}
const Field* operator->() const { return iter_; }
RepeatedFieldIterator& operator++() {
PERFETTO_DCHECK(iter_ != end_);
if (iter_ == last_) {
iter_ = end_;
return *this;
}
++iter_;
FindNextMatchingId();
return *this;
}
RepeatedFieldIterator operator++(int) {
PERFETTO_DCHECK(iter_ != end_);
RepeatedFieldIterator it(*this);
++(*this);
return it;
}
private:
void FindNextMatchingId() {
PERFETTO_DCHECK(iter_ != last_);
for (; iter_ != end_; ++iter_) {
if (iter_->id() == field_id_)
return;
}
iter_ = last_->valid() ? last_ : end_;
}
uint32_t field_id_;
// Initially points to the beginning of the repeated field storage, then is
// incremented as we call operator++().
const Field* iter_;
// Always points to fields_[size_], i.e. past the end of the storage.
const Field* end_;
// Always points to fields_[field_id].
const Field* last_;
};
// As RepeatedFieldIterator, but allows iterating over a packed repeated field
// (which will be initially stored as a single length-delimited field).
// See |GetPackedRepeatedField| for details.
//
// Assumes little endianness, and that the input buffers are well formed -
// containing an exact multiple of encoded elements.
template <proto_utils::ProtoWireType wire_type, typename CppType>
class PackedRepeatedFieldIterator {
public:
PackedRepeatedFieldIterator(const uint8_t* data_begin,
size_t size,
bool* parse_error_ptr)
: data_end_(data_begin ? data_begin + size : nullptr),
read_ptr_(data_begin),
parse_error_(parse_error_ptr) {
using proto_utils::ProtoWireType;
static_assert(wire_type == ProtoWireType::kVarInt ||
wire_type == ProtoWireType::kFixed32 ||
wire_type == ProtoWireType::kFixed64,
"invalid type");
PERFETTO_DCHECK(parse_error_ptr);
// Either the field is unset (and there are no data pointer), or the field
// is set with a zero length payload. Mark the iterator as invalid in both
// cases.
if (size == 0) {
curr_value_valid_ = false;
return;
}
if ((wire_type == ProtoWireType::kFixed32 && (size % 4) != 0) ||
(wire_type == ProtoWireType::kFixed64 && (size % 8) != 0)) {
*parse_error_ = true;
curr_value_valid_ = false;
return;
}
++(*this);
}
const CppType operator*() const { return curr_value_; }
explicit operator bool() const { return curr_value_valid_; }
PackedRepeatedFieldIterator& operator++() {
using proto_utils::ProtoWireType;
if (PERFETTO_UNLIKELY(!curr_value_valid_))
return *this;
if (PERFETTO_UNLIKELY(read_ptr_ == data_end_)) {
curr_value_valid_ = false;
return *this;
}
if (wire_type == ProtoWireType::kVarInt) {
uint64_t new_value = 0;
const uint8_t* new_pos =
proto_utils::ParseVarInt(read_ptr_, data_end_, &new_value);
if (PERFETTO_UNLIKELY(new_pos == read_ptr_)) {
// Failed to decode the varint (probably incomplete buffer).
*parse_error_ = true;
curr_value_valid_ = false;
} else {
read_ptr_ = new_pos;
curr_value_ = static_cast<CppType>(new_value);
}
} else { // kFixed32 or kFixed64
constexpr size_t kStep = wire_type == ProtoWireType::kFixed32 ? 4 : 8;
// NB: the raw buffer is not guaranteed to be aligned, so neither are
// these copies.
memcpy(&curr_value_, read_ptr_, sizeof(CppType));
read_ptr_ += kStep;
}
return *this;
}
PackedRepeatedFieldIterator operator++(int) {
PackedRepeatedFieldIterator it(*this);
++(*this);
return it;
}
private:
// Might be null if the backing proto field isn't set.
const uint8_t* const data_end_;
// The iterator looks ahead by an element, so |curr_value| holds the value
// to be returned when the caller dereferences the iterator, and |read_ptr_|
// points at the start of the next element to be decoded.
// |read_ptr_| might be null if the backing proto field isn't set.
const uint8_t* read_ptr_;
CppType curr_value_ = {};
// Set to false once we've exhausted the iterator, or encountered an error.
bool curr_value_valid_ = true;
// Where to set parsing errors, supplied by the caller.
bool* const parse_error_;
};
// This decoder loads all fields upfront, without recursing in nested messages.
// It is used as a base class for typed decoders generated by the pbzero plugin.
// The split between TypedProtoDecoderBase and TypedProtoDecoder<> is to have
// unique definition of functions like ParseAllFields() and ExpandHeapStorage().
// The storage (either on-stack or on-heap) for this class is organized as
// follows:
// |-------------------------- fields_ ----------------------|
// [ field 0 (invalid) ] [ fields 1 .. N ] [ repeated fields ]
// ^ ^
// num_fields_ size_
// Note that if a message has high field numbers, upon creation |size_| can be
// < |num_fields_| (until a heap expansion is hit while inserting).
class PERFETTO_EXPORT_COMPONENT TypedProtoDecoderBase : public ProtoDecoder {
public:
// If the field |id| is known at compile time, prefer the templated
// specialization at<kFieldNumber>().
const Field& Get(uint32_t id) const {
if (PERFETTO_LIKELY(id < num_fields_ && id < size_))
return fields_[id];
// If id >= num_fields_, the field id is invalid (was not known in the
// .proto) and we return the 0th field, which is always !valid().
// If id >= size_ and <= num_fields, the id is valid but the field has not
// been seen while decoding (hence the stack storage has not been expanded)
// so we return the 0th invalid field.
return fields_[0];
}
// Returns an object that allows to iterate over all instances of a repeated
// field given its id. Example usage:
// for (auto it = decoder.GetRepeated<int32_t>(N); it; ++it) { ... }
template <typename T>
RepeatedFieldIterator<T> GetRepeated(uint32_t field_id) const {
const Field* repeated_begin;
// The storage for repeated fields starts after the slot for the highest
// field id (refer to the diagram in the class-level comment). However, if
// a message has more than INITIAL_STACK_CAPACITY field there will be no
// slots available for the repeated fields (if ExpandHeapStorage() was not
// called). Imagine a message that has highest field id = 102 and that is
// still using the stack:
// [ F0 ] [ F1 ] ... [ F100 ] [ F101 ] [ F1012] [ repeated fields ]
// ^ num_fields_
// ^ size (== capacity)
if (PERFETTO_LIKELY(num_fields_ < size_)) {
repeated_begin = &fields_[num_fields_];
} else {
// This is the case of not having any storage space for repeated fields.
// This makes it so begin == end, so the iterator will just skip @ last.
repeated_begin = &fields_[size_];
}
const Field* repeated_end = &fields_[size_];
const Field* last = &Get(field_id);
return RepeatedFieldIterator<T>(field_id, repeated_begin, repeated_end,
last);
}
// Returns an objects that allows to iterate over all entries of a packed
// repeated field given its id and type. The |wire_type| is necessary for
// decoding the packed field, the |cpp_type| is for convenience & stronger
// typing.
//
// The caller must also supply a pointer to a bool that is set to true if the
// packed buffer is found to be malformed while iterating (so you need to
// exhaust the iterator if you want to check the full extent of the buffer).
//
// Note that unlike standard protobuf parsers, protozero does not allow
// treating of packed repeated fields as non-packed and vice-versa (therefore
// not making the packed option forwards and backwards compatible). So
// the caller needs to use the right accessor for correct results.
template <proto_utils::ProtoWireType wire_type, typename cpp_type>
PackedRepeatedFieldIterator<wire_type, cpp_type> GetPackedRepeated(
uint32_t field_id,
bool* parse_error_location) const {
const Field& field = Get(field_id);
if (field.valid() &&
field.type() == proto_utils::ProtoWireType::kLengthDelimited) {
return PackedRepeatedFieldIterator<wire_type, cpp_type>(
field.data(), field.size(), parse_error_location);
}
return PackedRepeatedFieldIterator<wire_type, cpp_type>(
nullptr, 0, parse_error_location);
}
protected:
TypedProtoDecoderBase(Field* storage,
uint32_t num_fields,
uint32_t capacity,
const uint8_t* buffer,
size_t length)
: ProtoDecoder(buffer, length),
fields_(storage),
num_fields_(num_fields),
// The reason for "capacity -1" is to avoid hitting the expansion path
// in TypedProtoDecoderBase::ParseAllFields() when we are just setting
// fields < INITIAL_STACK_CAPACITY (which is the most common case).
size_(std::min(num_fields, capacity - 1)),
capacity_(capacity) {
// The reason why Field needs to be trivially de/constructible is to avoid
// implicit initializers on all the ~1000 entries. We need it to initialize
// only on the first |max_field_id| fields, the remaining capacity doesn't
// require initialization.
static_assert(std::is_trivially_constructible<Field>::value &&
std::is_trivially_destructible<Field>::value &&
std::is_trivial<Field>::value,
"Field must be a trivial aggregate type");
memset(fields_, 0, sizeof(Field) * capacity_);
PERFETTO_DCHECK(capacity > 0);
}
void ParseAllFields();
// Called when the default on-stack storage is exhausted and new repeated
// fields need to be pushed.
void ExpandHeapStorage();
// Used only in presence of a large number of repeated fields, when the
// default on-stack storage is exhausted.
std::unique_ptr<Field[]> heap_storage_;
// Points to the storage, either on-stack (default, provided by the template
// specialization) or |heap_storage_| after ExpandHeapStorage() is called, in
// case of a large number of repeated fields.
Field* fields_;
// Number of known fields, without accounting repeated storage. This is equal
// to MAX_FIELD_ID + 1 (to account for the invalid 0th field). It never
// changes after construction.
// This is unrelated with |size_| and |capacity_|. If the highest field id of
// a proto message is 131, |num_fields_| will be = 132 but, on initialization,
// |size_| = |capacity_| = 100 (INITIAL_STACK_CAPACITY).
// One cannot generally assume that |fields_| has enough storage to
// dereference every field. That is only true:
// - For field ids < INITIAL_STACK_CAPACITY.
// - After the first call to ExpandHeapStorage().
uint32_t num_fields_;
// Number of active |fields_| entries. This is initially equal to
// min(num_fields_, INITIAL_STACK_CAPACITY - 1) and after ExpandHeapStorage()
// becomes == |num_fields_|. If the message has non-packed repeated fields, it
// can grow further, up to |capacity_|.
// |size_| is always <= |capacity_|. But |num_fields_| can be > |size_|.
uint32_t size_;
// Initially equal to kFieldsCapacity of the TypedProtoDecoder
// specialization. Can grow when falling back on heap-based storage, in which
// case it represents the size (#fields with each entry of a repeated field
// counted individually) of the |heap_storage_| array.
uint32_t capacity_;
};
// This constant is a tradeoff between having a larger stack frame and being
// able to decode field IDs up to N (or N - num_fields repeated fields) without
// falling back on the heap.
#define PROTOZERO_DECODER_INITIAL_STACK_CAPACITY 100
// Template class instantiated by the auto-generated decoder classes declared in
// xxx.pbzero.h files.
template <int MAX_FIELD_ID, bool HAS_NONPACKED_REPEATED_FIELDS>
class TypedProtoDecoder : public TypedProtoDecoderBase {
public:
TypedProtoDecoder(const uint8_t* buffer, size_t length)
: TypedProtoDecoderBase(on_stack_storage_,
/*num_fields=*/MAX_FIELD_ID + 1,
PROTOZERO_DECODER_INITIAL_STACK_CAPACITY,
buffer,
length) {
TypedProtoDecoderBase::ParseAllFields();
}
template <uint32_t FIELD_ID>
const Field& at() const {
static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
// If the field id is < the on-stack capacity, it's safe to always
// dereference |fields_|, whether it's still using the stack or it fell
// back on the heap. Because both terms of the if () are known at compile
// time, the compiler elides the branch for ids < INITIAL_STACK_CAPACITY.
if (FIELD_ID < PROTOZERO_DECODER_INITIAL_STACK_CAPACITY) {
return fields_[FIELD_ID];
} else {
// Otherwise use the slowpath Get() which will do a runtime check.
return Get(FIELD_ID);
}
}
TypedProtoDecoder(TypedProtoDecoder&& other) noexcept
: TypedProtoDecoderBase(std::move(other)) {
// If the moved-from decoder was using on-stack storage, we need to update
// our pointer to point to this decoder's on-stack storage.
if (fields_ == other.on_stack_storage_) {
fields_ = on_stack_storage_;
memcpy(on_stack_storage_, other.on_stack_storage_,
sizeof(on_stack_storage_));
}
}
private:
Field on_stack_storage_[PROTOZERO_DECODER_INITIAL_STACK_CAPACITY];
};
} // namespace protozero
#endif // INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
#include <stddef.h>
#include <stdint.h>
// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
namespace perfetto {
namespace protos {
namespace pbzero {
class ChromeActiveProcesses;
class ChromeApplicationStateInfo;
class ChromeCompositorSchedulerState;
class ChromeContentSettingsEventInfo;
class ChromeFrameReporter;
class ChromeHistogramSample;
class ChromeKeyedService;
class ChromeLatencyInfo;
class ChromeLegacyIpc;
class ChromeMessagePump;
class ChromeMojoEventInfo;
class ChromeRendererSchedulerState;
class ChromeUserEvent;
class ChromeWindowHandleEventInfo;
class DebugAnnotation;
class LogMessage;
class Screenshot;
class SourceLocation;
class TaskExecution;
class TrackEvent_LegacyEvent;
namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
enum FlowDirection : int32_t;
} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
enum InstantEventScope : int32_t;
} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
namespace perfetto_pbzero_enum_TrackEvent {
enum Type : int32_t;
} // namespace perfetto_pbzero_enum_TrackEvent
using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
} // Namespace pbzero.
} // Namespace protos.
} // Namespace perfetto.
namespace perfetto {
namespace protos {
namespace pbzero {
namespace perfetto_pbzero_enum_TrackEvent {
enum Type : int32_t {
TYPE_UNSPECIFIED = 0,
TYPE_SLICE_BEGIN = 1,
TYPE_SLICE_END = 2,
TYPE_INSTANT = 3,
TYPE_COUNTER = 4,
};
} // namespace perfetto_pbzero_enum_TrackEvent
using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
constexpr TrackEvent_Type TrackEvent_Type_MIN = TrackEvent_Type::TYPE_UNSPECIFIED;
constexpr TrackEvent_Type TrackEvent_Type_MAX = TrackEvent_Type::TYPE_COUNTER;
PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
const char* TrackEvent_Type_Name(::perfetto::protos::pbzero::TrackEvent_Type value) {
switch (value) {
case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_UNSPECIFIED:
return "TYPE_UNSPECIFIED";
case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_BEGIN:
return "TYPE_SLICE_BEGIN";
case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_END:
return "TYPE_SLICE_END";
case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_INSTANT:
return "TYPE_INSTANT";
case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_COUNTER:
return "TYPE_COUNTER";
}
return "PBZERO_UNKNOWN_ENUM_VALUE";
}
namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
enum FlowDirection : int32_t {
FLOW_UNSPECIFIED = 0,
FLOW_IN = 1,
FLOW_OUT = 2,
FLOW_INOUT = 3,
};
} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED;
constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT;
PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
const char* TrackEvent_LegacyEvent_FlowDirection_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection value) {
switch (value) {
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED:
return "FLOW_UNSPECIFIED";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_IN:
return "FLOW_IN";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_OUT:
return "FLOW_OUT";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT:
return "FLOW_INOUT";
}
return "PBZERO_UNKNOWN_ENUM_VALUE";
}
namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
enum InstantEventScope : int32_t {
SCOPE_UNSPECIFIED = 0,
SCOPE_GLOBAL = 1,
SCOPE_PROCESS = 2,
SCOPE_THREAD = 3,
};
} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED;
constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD;
PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
const char* TrackEvent_LegacyEvent_InstantEventScope_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope value) {
switch (value) {
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED:
return "SCOPE_UNSPECIFIED";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_GLOBAL:
return "SCOPE_GLOBAL";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_PROCESS:
return "SCOPE_PROCESS";
case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD:
return "SCOPE_THREAD";
}
return "PBZERO_UNKNOWN_ENUM_VALUE";
}
class EventName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
public:
EventName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
explicit EventName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
explicit EventName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
bool has_iid() const { return at<1>().valid(); }
uint64_t iid() const { return at<1>().as_uint64(); }
bool has_name() const { return at<2>().valid(); }
::protozero::ConstChars name() const { return at<2>().as_string(); }
};
class EventName : public ::protozero::Message {
public:
using Decoder = EventName_Decoder;
enum : int32_t {
kIidFieldNumber = 1,
kNameFieldNumber = 2,
};
static constexpr const char* GetName() { return ".perfetto.protos.EventName"; }
using FieldMetadata_Iid =
::protozero::proto_utils::FieldMetadata<
1,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
EventName>;
static constexpr FieldMetadata_Iid kIid{};
void set_iid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_Name =
::protozero::proto_utils::FieldMetadata<
2,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kString,
std::string,
EventName>;
static constexpr FieldMetadata_Name kName{};
void set_name(const char* data, size_t size) {
AppendBytes(FieldMetadata_Name::kFieldId, data, size);
}
void set_name(::protozero::ConstChars chars) {
AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
}
void set_name(std::string value) {
static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kString>
::Append(*this, field_id, value);
}
};
class EventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
public:
EventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
explicit EventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
explicit EventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
bool has_iid() const { return at<1>().valid(); }
uint64_t iid() const { return at<1>().as_uint64(); }
bool has_name() const { return at<2>().valid(); }
::protozero::ConstChars name() const { return at<2>().as_string(); }
};
class EventCategory : public ::protozero::Message {
public:
using Decoder = EventCategory_Decoder;
enum : int32_t {
kIidFieldNumber = 1,
kNameFieldNumber = 2,
};
static constexpr const char* GetName() { return ".perfetto.protos.EventCategory"; }
using FieldMetadata_Iid =
::protozero::proto_utils::FieldMetadata<
1,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
EventCategory>;
static constexpr FieldMetadata_Iid kIid{};
void set_iid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_Name =
::protozero::proto_utils::FieldMetadata<
2,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kString,
std::string,
EventCategory>;
static constexpr FieldMetadata_Name kName{};
void set_name(const char* data, size_t size) {
AppendBytes(FieldMetadata_Name::kFieldId, data, size);
}
void set_name(::protozero::ConstChars chars) {
AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
}
void set_name(std::string value) {
static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kString>
::Append(*this, field_id, value);
}
};
class TrackEventDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/45, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
public:
TrackEventDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
explicit TrackEventDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
explicit TrackEventDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
bool has_track_uuid() const { return at<11>().valid(); }
uint64_t track_uuid() const { return at<11>().as_uint64(); }
bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
};
class TrackEventDefaults : public ::protozero::Message {
public:
using Decoder = TrackEventDefaults_Decoder;
enum : int32_t {
kTrackUuidFieldNumber = 11,
kExtraCounterTrackUuidsFieldNumber = 31,
kExtraDoubleCounterTrackUuidsFieldNumber = 45,
};
static constexpr const char* GetName() { return ".perfetto.protos.TrackEventDefaults"; }
using FieldMetadata_TrackUuid =
::protozero::proto_utils::FieldMetadata<
11,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEventDefaults>;
static constexpr FieldMetadata_TrackUuid kTrackUuid{};
void set_track_uuid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TrackUuid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraCounterTrackUuids =
::protozero::proto_utils::FieldMetadata<
31,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEventDefaults>;
static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
void add_extra_counter_track_uuids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraDoubleCounterTrackUuids =
::protozero::proto_utils::FieldMetadata<
45,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEventDefaults>;
static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
void add_extra_double_counter_track_uuids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
};
class TrackEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/50, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
public:
TrackEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
explicit TrackEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
explicit TrackEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
bool has_category_iids() const { return at<3>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> category_iids() const { return GetRepeated<uint64_t>(3); }
bool has_categories() const { return at<22>().valid(); }
::protozero::RepeatedFieldIterator<::protozero::ConstChars> categories() const { return GetRepeated<::protozero::ConstChars>(22); }
bool has_name_iid() const { return at<10>().valid(); }
uint64_t name_iid() const { return at<10>().as_uint64(); }
bool has_name() const { return at<23>().valid(); }
::protozero::ConstChars name() const { return at<23>().as_string(); }
bool has_type() const { return at<9>().valid(); }
int32_t type() const { return at<9>().as_int32(); }
bool has_track_uuid() const { return at<11>().valid(); }
uint64_t track_uuid() const { return at<11>().as_uint64(); }
bool has_counter_value() const { return at<30>().valid(); }
int64_t counter_value() const { return at<30>().as_int64(); }
bool has_double_counter_value() const { return at<44>().valid(); }
double double_counter_value() const { return at<44>().as_double(); }
bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
bool has_extra_counter_values() const { return at<12>().valid(); }
::protozero::RepeatedFieldIterator<int64_t> extra_counter_values() const { return GetRepeated<int64_t>(12); }
bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
bool has_extra_double_counter_values() const { return at<46>().valid(); }
::protozero::RepeatedFieldIterator<double> extra_double_counter_values() const { return GetRepeated<double>(46); }
bool has_flow_ids_old() const { return at<36>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> flow_ids_old() const { return GetRepeated<uint64_t>(36); }
bool has_flow_ids() const { return at<47>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> flow_ids() const { return GetRepeated<uint64_t>(47); }
bool has_terminating_flow_ids_old() const { return at<42>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids_old() const { return GetRepeated<uint64_t>(42); }
bool has_terminating_flow_ids() const { return at<48>().valid(); }
::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids() const { return GetRepeated<uint64_t>(48); }
bool has_debug_annotations() const { return at<4>().valid(); }
::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(4); }
bool has_task_execution() const { return at<5>().valid(); }
::protozero::ConstBytes task_execution() const { return at<5>().as_bytes(); }
bool has_log_message() const { return at<21>().valid(); }
::protozero::ConstBytes log_message() const { return at<21>().as_bytes(); }
bool has_cc_scheduler_state() const { return at<24>().valid(); }
::protozero::ConstBytes cc_scheduler_state() const { return at<24>().as_bytes(); }
bool has_chrome_user_event() const { return at<25>().valid(); }
::protozero::ConstBytes chrome_user_event() const { return at<25>().as_bytes(); }
bool has_chrome_keyed_service() const { return at<26>().valid(); }
::protozero::ConstBytes chrome_keyed_service() const { return at<26>().as_bytes(); }
bool has_chrome_legacy_ipc() const { return at<27>().valid(); }
::protozero::ConstBytes chrome_legacy_ipc() const { return at<27>().as_bytes(); }
bool has_chrome_histogram_sample() const { return at<28>().valid(); }
::protozero::ConstBytes chrome_histogram_sample() const { return at<28>().as_bytes(); }
bool has_chrome_latency_info() const { return at<29>().valid(); }
::protozero::ConstBytes chrome_latency_info() const { return at<29>().as_bytes(); }
bool has_chrome_frame_reporter() const { return at<32>().valid(); }
::protozero::ConstBytes chrome_frame_reporter() const { return at<32>().as_bytes(); }
bool has_chrome_application_state_info() const { return at<39>().valid(); }
::protozero::ConstBytes chrome_application_state_info() const { return at<39>().as_bytes(); }
bool has_chrome_renderer_scheduler_state() const { return at<40>().valid(); }
::protozero::ConstBytes chrome_renderer_scheduler_state() const { return at<40>().as_bytes(); }
bool has_chrome_window_handle_event_info() const { return at<41>().valid(); }
::protozero::ConstBytes chrome_window_handle_event_info() const { return at<41>().as_bytes(); }
bool has_chrome_content_settings_event_info() const { return at<43>().valid(); }
::protozero::ConstBytes chrome_content_settings_event_info() const { return at<43>().as_bytes(); }
bool has_chrome_active_processes() const { return at<49>().valid(); }
::protozero::ConstBytes chrome_active_processes() const { return at<49>().as_bytes(); }
bool has_screenshot() const { return at<50>().valid(); }
::protozero::ConstBytes screenshot() const { return at<50>().as_bytes(); }
bool has_source_location() const { return at<33>().valid(); }
::protozero::ConstBytes source_location() const { return at<33>().as_bytes(); }
bool has_source_location_iid() const { return at<34>().valid(); }
uint64_t source_location_iid() const { return at<34>().as_uint64(); }
bool has_chrome_message_pump() const { return at<35>().valid(); }
::protozero::ConstBytes chrome_message_pump() const { return at<35>().as_bytes(); }
bool has_chrome_mojo_event_info() const { return at<38>().valid(); }
::protozero::ConstBytes chrome_mojo_event_info() const { return at<38>().as_bytes(); }
bool has_timestamp_delta_us() const { return at<1>().valid(); }
int64_t timestamp_delta_us() const { return at<1>().as_int64(); }
bool has_timestamp_absolute_us() const { return at<16>().valid(); }
int64_t timestamp_absolute_us() const { return at<16>().as_int64(); }
bool has_thread_time_delta_us() const { return at<2>().valid(); }
int64_t thread_time_delta_us() const { return at<2>().as_int64(); }
bool has_thread_time_absolute_us() const { return at<17>().valid(); }
int64_t thread_time_absolute_us() const { return at<17>().as_int64(); }
bool has_thread_instruction_count_delta() const { return at<8>().valid(); }
int64_t thread_instruction_count_delta() const { return at<8>().as_int64(); }
bool has_thread_instruction_count_absolute() const { return at<20>().valid(); }
int64_t thread_instruction_count_absolute() const { return at<20>().as_int64(); }
bool has_legacy_event() const { return at<6>().valid(); }
::protozero::ConstBytes legacy_event() const { return at<6>().as_bytes(); }
};
class TrackEvent : public ::protozero::Message {
public:
using Decoder = TrackEvent_Decoder;
enum : int32_t {
kCategoryIidsFieldNumber = 3,
kCategoriesFieldNumber = 22,
kNameIidFieldNumber = 10,
kNameFieldNumber = 23,
kTypeFieldNumber = 9,
kTrackUuidFieldNumber = 11,
kCounterValueFieldNumber = 30,
kDoubleCounterValueFieldNumber = 44,
kExtraCounterTrackUuidsFieldNumber = 31,
kExtraCounterValuesFieldNumber = 12,
kExtraDoubleCounterTrackUuidsFieldNumber = 45,
kExtraDoubleCounterValuesFieldNumber = 46,
kFlowIdsOldFieldNumber = 36,
kFlowIdsFieldNumber = 47,
kTerminatingFlowIdsOldFieldNumber = 42,
kTerminatingFlowIdsFieldNumber = 48,
kDebugAnnotationsFieldNumber = 4,
kTaskExecutionFieldNumber = 5,
kLogMessageFieldNumber = 21,
kCcSchedulerStateFieldNumber = 24,
kChromeUserEventFieldNumber = 25,
kChromeKeyedServiceFieldNumber = 26,
kChromeLegacyIpcFieldNumber = 27,
kChromeHistogramSampleFieldNumber = 28,
kChromeLatencyInfoFieldNumber = 29,
kChromeFrameReporterFieldNumber = 32,
kChromeApplicationStateInfoFieldNumber = 39,
kChromeRendererSchedulerStateFieldNumber = 40,
kChromeWindowHandleEventInfoFieldNumber = 41,
kChromeContentSettingsEventInfoFieldNumber = 43,
kChromeActiveProcessesFieldNumber = 49,
kScreenshotFieldNumber = 50,
kSourceLocationFieldNumber = 33,
kSourceLocationIidFieldNumber = 34,
kChromeMessagePumpFieldNumber = 35,
kChromeMojoEventInfoFieldNumber = 38,
kTimestampDeltaUsFieldNumber = 1,
kTimestampAbsoluteUsFieldNumber = 16,
kThreadTimeDeltaUsFieldNumber = 2,
kThreadTimeAbsoluteUsFieldNumber = 17,
kThreadInstructionCountDeltaFieldNumber = 8,
kThreadInstructionCountAbsoluteFieldNumber = 20,
kLegacyEventFieldNumber = 6,
};
static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent"; }
using LegacyEvent = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent;
using Type = ::perfetto::protos::pbzero::TrackEvent_Type;
static inline const char* Type_Name(Type value) {
return ::perfetto::protos::pbzero::TrackEvent_Type_Name(value);
}
static inline const Type TYPE_UNSPECIFIED = Type::TYPE_UNSPECIFIED;
static inline const Type TYPE_SLICE_BEGIN = Type::TYPE_SLICE_BEGIN;
static inline const Type TYPE_SLICE_END = Type::TYPE_SLICE_END;
static inline const Type TYPE_INSTANT = Type::TYPE_INSTANT;
static inline const Type TYPE_COUNTER = Type::TYPE_COUNTER;
using FieldMetadata_CategoryIids =
::protozero::proto_utils::FieldMetadata<
3,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_CategoryIids kCategoryIids{};
void add_category_iids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_CategoryIids::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_Categories =
::protozero::proto_utils::FieldMetadata<
22,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kString,
std::string,
TrackEvent>;
static constexpr FieldMetadata_Categories kCategories{};
void add_categories(const char* data, size_t size) {
AppendBytes(FieldMetadata_Categories::kFieldId, data, size);
}
void add_categories(::protozero::ConstChars chars) {
AppendBytes(FieldMetadata_Categories::kFieldId, chars.data, chars.size);
}
void add_categories(std::string value) {
static constexpr uint32_t field_id = FieldMetadata_Categories::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kString>
::Append(*this, field_id, value);
}
using FieldMetadata_NameIid =
::protozero::proto_utils::FieldMetadata<
10,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_NameIid kNameIid{};
void set_name_iid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_Name =
::protozero::proto_utils::FieldMetadata<
23,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kString,
std::string,
TrackEvent>;
static constexpr FieldMetadata_Name kName{};
void set_name(const char* data, size_t size) {
AppendBytes(FieldMetadata_Name::kFieldId, data, size);
}
void set_name(::protozero::ConstChars chars) {
AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
}
void set_name(std::string value) {
static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kString>
::Append(*this, field_id, value);
}
using FieldMetadata_Type =
::protozero::proto_utils::FieldMetadata<
9,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kEnum,
TrackEvent_Type,
TrackEvent>;
static constexpr FieldMetadata_Type kType{};
void set_type(TrackEvent_Type value) {
static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kEnum>
::Append(*this, field_id, value);
}
using FieldMetadata_TrackUuid =
::protozero::proto_utils::FieldMetadata<
11,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_TrackUuid kTrackUuid{};
void set_track_uuid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TrackUuid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_CounterValue =
::protozero::proto_utils::FieldMetadata<
30,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_CounterValue kCounterValue{};
void set_counter_value(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_CounterValue::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_DoubleCounterValue =
::protozero::proto_utils::FieldMetadata<
44,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kDouble,
double,
TrackEvent>;
static constexpr FieldMetadata_DoubleCounterValue kDoubleCounterValue{};
void set_double_counter_value(double value) {
static constexpr uint32_t field_id = FieldMetadata_DoubleCounterValue::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kDouble>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraCounterTrackUuids =
::protozero::proto_utils::FieldMetadata<
31,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
void add_extra_counter_track_uuids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraCounterValues =
::protozero::proto_utils::FieldMetadata<
12,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_ExtraCounterValues kExtraCounterValues{};
void add_extra_counter_values(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraCounterValues::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraDoubleCounterTrackUuids =
::protozero::proto_utils::FieldMetadata<
45,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
void add_extra_double_counter_track_uuids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_ExtraDoubleCounterValues =
::protozero::proto_utils::FieldMetadata<
46,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kDouble,
double,
TrackEvent>;
static constexpr FieldMetadata_ExtraDoubleCounterValues kExtraDoubleCounterValues{};
void add_extra_double_counter_values(double value) {
static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterValues::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kDouble>
::Append(*this, field_id, value);
}
using FieldMetadata_FlowIdsOld =
::protozero::proto_utils::FieldMetadata<
36,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_FlowIdsOld kFlowIdsOld{};
void add_flow_ids_old(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_FlowIdsOld::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_FlowIds =
::protozero::proto_utils::FieldMetadata<
47,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kFixed64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_FlowIds kFlowIds{};
void add_flow_ids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_FlowIds::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kFixed64>
::Append(*this, field_id, value);
}
using FieldMetadata_TerminatingFlowIdsOld =
::protozero::proto_utils::FieldMetadata<
42,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_TerminatingFlowIdsOld kTerminatingFlowIdsOld{};
void add_terminating_flow_ids_old(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIdsOld::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_TerminatingFlowIds =
::protozero::proto_utils::FieldMetadata<
48,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kFixed64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_TerminatingFlowIds kTerminatingFlowIds{};
void add_terminating_flow_ids(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIds::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kFixed64>
::Append(*this, field_id, value);
}
using FieldMetadata_DebugAnnotations =
::protozero::proto_utils::FieldMetadata<
4,
::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
::protozero::proto_utils::ProtoSchemaType::kMessage,
DebugAnnotation,
TrackEvent>;
static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
template <typename T = DebugAnnotation> T* add_debug_annotations() {
return BeginNestedMessage<T>(4);
}
using FieldMetadata_TaskExecution =
::protozero::proto_utils::FieldMetadata<
5,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
TaskExecution,
TrackEvent>;
static constexpr FieldMetadata_TaskExecution kTaskExecution{};
template <typename T = TaskExecution> T* set_task_execution() {
return BeginNestedMessage<T>(5);
}
using FieldMetadata_LogMessage =
::protozero::proto_utils::FieldMetadata<
21,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
LogMessage,
TrackEvent>;
static constexpr FieldMetadata_LogMessage kLogMessage{};
template <typename T = LogMessage> T* set_log_message() {
return BeginNestedMessage<T>(21);
}
using FieldMetadata_CcSchedulerState =
::protozero::proto_utils::FieldMetadata<
24,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeCompositorSchedulerState,
TrackEvent>;
static constexpr FieldMetadata_CcSchedulerState kCcSchedulerState{};
template <typename T = ChromeCompositorSchedulerState> T* set_cc_scheduler_state() {
return BeginNestedMessage<T>(24);
}
using FieldMetadata_ChromeUserEvent =
::protozero::proto_utils::FieldMetadata<
25,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeUserEvent,
TrackEvent>;
static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent{};
template <typename T = ChromeUserEvent> T* set_chrome_user_event() {
return BeginNestedMessage<T>(25);
}
using FieldMetadata_ChromeKeyedService =
::protozero::proto_utils::FieldMetadata<
26,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeKeyedService,
TrackEvent>;
static constexpr FieldMetadata_ChromeKeyedService kChromeKeyedService{};
template <typename T = ChromeKeyedService> T* set_chrome_keyed_service() {
return BeginNestedMessage<T>(26);
}
using FieldMetadata_ChromeLegacyIpc =
::protozero::proto_utils::FieldMetadata<
27,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeLegacyIpc,
TrackEvent>;
static constexpr FieldMetadata_ChromeLegacyIpc kChromeLegacyIpc{};
template <typename T = ChromeLegacyIpc> T* set_chrome_legacy_ipc() {
return BeginNestedMessage<T>(27);
}
using FieldMetadata_ChromeHistogramSample =
::protozero::proto_utils::FieldMetadata<
28,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeHistogramSample,
TrackEvent>;
static constexpr FieldMetadata_ChromeHistogramSample kChromeHistogramSample{};
template <typename T = ChromeHistogramSample> T* set_chrome_histogram_sample() {
return BeginNestedMessage<T>(28);
}
using FieldMetadata_ChromeLatencyInfo =
::protozero::proto_utils::FieldMetadata<
29,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeLatencyInfo,
TrackEvent>;
static constexpr FieldMetadata_ChromeLatencyInfo kChromeLatencyInfo{};
template <typename T = ChromeLatencyInfo> T* set_chrome_latency_info() {
return BeginNestedMessage<T>(29);
}
using FieldMetadata_ChromeFrameReporter =
::protozero::proto_utils::FieldMetadata<
32,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeFrameReporter,
TrackEvent>;
static constexpr FieldMetadata_ChromeFrameReporter kChromeFrameReporter{};
template <typename T = ChromeFrameReporter> T* set_chrome_frame_reporter() {
return BeginNestedMessage<T>(32);
}
using FieldMetadata_ChromeApplicationStateInfo =
::protozero::proto_utils::FieldMetadata<
39,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeApplicationStateInfo,
TrackEvent>;
static constexpr FieldMetadata_ChromeApplicationStateInfo kChromeApplicationStateInfo{};
template <typename T = ChromeApplicationStateInfo> T* set_chrome_application_state_info() {
return BeginNestedMessage<T>(39);
}
using FieldMetadata_ChromeRendererSchedulerState =
::protozero::proto_utils::FieldMetadata<
40,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeRendererSchedulerState,
TrackEvent>;
static constexpr FieldMetadata_ChromeRendererSchedulerState kChromeRendererSchedulerState{};
template <typename T = ChromeRendererSchedulerState> T* set_chrome_renderer_scheduler_state() {
return BeginNestedMessage<T>(40);
}
using FieldMetadata_ChromeWindowHandleEventInfo =
::protozero::proto_utils::FieldMetadata<
41,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeWindowHandleEventInfo,
TrackEvent>;
static constexpr FieldMetadata_ChromeWindowHandleEventInfo kChromeWindowHandleEventInfo{};
template <typename T = ChromeWindowHandleEventInfo> T* set_chrome_window_handle_event_info() {
return BeginNestedMessage<T>(41);
}
using FieldMetadata_ChromeContentSettingsEventInfo =
::protozero::proto_utils::FieldMetadata<
43,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeContentSettingsEventInfo,
TrackEvent>;
static constexpr FieldMetadata_ChromeContentSettingsEventInfo kChromeContentSettingsEventInfo{};
template <typename T = ChromeContentSettingsEventInfo> T* set_chrome_content_settings_event_info() {
return BeginNestedMessage<T>(43);
}
using FieldMetadata_ChromeActiveProcesses =
::protozero::proto_utils::FieldMetadata<
49,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeActiveProcesses,
TrackEvent>;
static constexpr FieldMetadata_ChromeActiveProcesses kChromeActiveProcesses{};
template <typename T = ChromeActiveProcesses> T* set_chrome_active_processes() {
return BeginNestedMessage<T>(49);
}
using FieldMetadata_Screenshot =
::protozero::proto_utils::FieldMetadata<
50,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
Screenshot,
TrackEvent>;
static constexpr FieldMetadata_Screenshot kScreenshot{};
template <typename T = Screenshot> T* set_screenshot() {
return BeginNestedMessage<T>(50);
}
using FieldMetadata_SourceLocation =
::protozero::proto_utils::FieldMetadata<
33,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
SourceLocation,
TrackEvent>;
static constexpr FieldMetadata_SourceLocation kSourceLocation{};
template <typename T = SourceLocation> T* set_source_location() {
return BeginNestedMessage<T>(33);
}
using FieldMetadata_SourceLocationIid =
::protozero::proto_utils::FieldMetadata<
34,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent>;
static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
void set_source_location_iid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_ChromeMessagePump =
::protozero::proto_utils::FieldMetadata<
35,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeMessagePump,
TrackEvent>;
static constexpr FieldMetadata_ChromeMessagePump kChromeMessagePump{};
template <typename T = ChromeMessagePump> T* set_chrome_message_pump() {
return BeginNestedMessage<T>(35);
}
using FieldMetadata_ChromeMojoEventInfo =
::protozero::proto_utils::FieldMetadata<
38,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
ChromeMojoEventInfo,
TrackEvent>;
static constexpr FieldMetadata_ChromeMojoEventInfo kChromeMojoEventInfo{};
template <typename T = ChromeMojoEventInfo> T* set_chrome_mojo_event_info() {
return BeginNestedMessage<T>(38);
}
using FieldMetadata_TimestampDeltaUs =
::protozero::proto_utils::FieldMetadata<
1,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs{};
void set_timestamp_delta_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TimestampDeltaUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_TimestampAbsoluteUs =
::protozero::proto_utils::FieldMetadata<
16,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_TimestampAbsoluteUs kTimestampAbsoluteUs{};
void set_timestamp_absolute_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_TimestampAbsoluteUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadTimeDeltaUs =
::protozero::proto_utils::FieldMetadata<
2,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_ThreadTimeDeltaUs kThreadTimeDeltaUs{};
void set_thread_time_delta_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadTimeDeltaUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadTimeAbsoluteUs =
::protozero::proto_utils::FieldMetadata<
17,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_ThreadTimeAbsoluteUs kThreadTimeAbsoluteUs{};
void set_thread_time_absolute_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadTimeAbsoluteUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadInstructionCountDelta =
::protozero::proto_utils::FieldMetadata<
8,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_ThreadInstructionCountDelta kThreadInstructionCountDelta{};
void set_thread_instruction_count_delta(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountDelta::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadInstructionCountAbsolute =
::protozero::proto_utils::FieldMetadata<
20,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent>;
static constexpr FieldMetadata_ThreadInstructionCountAbsolute kThreadInstructionCountAbsolute{};
void set_thread_instruction_count_absolute(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountAbsolute::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_LegacyEvent =
::protozero::proto_utils::FieldMetadata<
6,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kMessage,
TrackEvent_LegacyEvent,
TrackEvent>;
static constexpr FieldMetadata_LegacyEvent kLegacyEvent{};
template <typename T = TrackEvent_LegacyEvent> T* set_legacy_event() {
return BeginNestedMessage<T>(6);
}
};
class TrackEvent_LegacyEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
public:
TrackEvent_LegacyEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
explicit TrackEvent_LegacyEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
explicit TrackEvent_LegacyEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
bool has_name_iid() const { return at<1>().valid(); }
uint64_t name_iid() const { return at<1>().as_uint64(); }
bool has_phase() const { return at<2>().valid(); }
int32_t phase() const { return at<2>().as_int32(); }
bool has_duration_us() const { return at<3>().valid(); }
int64_t duration_us() const { return at<3>().as_int64(); }
bool has_thread_duration_us() const { return at<4>().valid(); }
int64_t thread_duration_us() const { return at<4>().as_int64(); }
bool has_thread_instruction_delta() const { return at<15>().valid(); }
int64_t thread_instruction_delta() const { return at<15>().as_int64(); }
bool has_unscoped_id() const { return at<6>().valid(); }
uint64_t unscoped_id() const { return at<6>().as_uint64(); }
bool has_local_id() const { return at<10>().valid(); }
uint64_t local_id() const { return at<10>().as_uint64(); }
bool has_global_id() const { return at<11>().valid(); }
uint64_t global_id() const { return at<11>().as_uint64(); }
bool has_id_scope() const { return at<7>().valid(); }
::protozero::ConstChars id_scope() const { return at<7>().as_string(); }
bool has_use_async_tts() const { return at<9>().valid(); }
bool use_async_tts() const { return at<9>().as_bool(); }
bool has_bind_id() const { return at<8>().valid(); }
uint64_t bind_id() const { return at<8>().as_uint64(); }
bool has_bind_to_enclosing() const { return at<12>().valid(); }
bool bind_to_enclosing() const { return at<12>().as_bool(); }
bool has_flow_direction() const { return at<13>().valid(); }
int32_t flow_direction() const { return at<13>().as_int32(); }
bool has_instant_event_scope() const { return at<14>().valid(); }
int32_t instant_event_scope() const { return at<14>().as_int32(); }
bool has_pid_override() const { return at<18>().valid(); }
int32_t pid_override() const { return at<18>().as_int32(); }
bool has_tid_override() const { return at<19>().valid(); }
int32_t tid_override() const { return at<19>().as_int32(); }
};
class TrackEvent_LegacyEvent : public ::protozero::Message {
public:
using Decoder = TrackEvent_LegacyEvent_Decoder;
enum : int32_t {
kNameIidFieldNumber = 1,
kPhaseFieldNumber = 2,
kDurationUsFieldNumber = 3,
kThreadDurationUsFieldNumber = 4,
kThreadInstructionDeltaFieldNumber = 15,
kUnscopedIdFieldNumber = 6,
kLocalIdFieldNumber = 10,
kGlobalIdFieldNumber = 11,
kIdScopeFieldNumber = 7,
kUseAsyncTtsFieldNumber = 9,
kBindIdFieldNumber = 8,
kBindToEnclosingFieldNumber = 12,
kFlowDirectionFieldNumber = 13,
kInstantEventScopeFieldNumber = 14,
kPidOverrideFieldNumber = 18,
kTidOverrideFieldNumber = 19,
};
static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent.LegacyEvent"; }
using FlowDirection = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection;
static inline const char* FlowDirection_Name(FlowDirection value) {
return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection_Name(value);
}
using InstantEventScope = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope;
static inline const char* InstantEventScope_Name(InstantEventScope value) {
return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope_Name(value);
}
static inline const FlowDirection FLOW_UNSPECIFIED = FlowDirection::FLOW_UNSPECIFIED;
static inline const FlowDirection FLOW_IN = FlowDirection::FLOW_IN;
static inline const FlowDirection FLOW_OUT = FlowDirection::FLOW_OUT;
static inline const FlowDirection FLOW_INOUT = FlowDirection::FLOW_INOUT;
static inline const InstantEventScope SCOPE_UNSPECIFIED = InstantEventScope::SCOPE_UNSPECIFIED;
static inline const InstantEventScope SCOPE_GLOBAL = InstantEventScope::SCOPE_GLOBAL;
static inline const InstantEventScope SCOPE_PROCESS = InstantEventScope::SCOPE_PROCESS;
static inline const InstantEventScope SCOPE_THREAD = InstantEventScope::SCOPE_THREAD;
using FieldMetadata_NameIid =
::protozero::proto_utils::FieldMetadata<
1,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_NameIid kNameIid{};
void set_name_iid(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_Phase =
::protozero::proto_utils::FieldMetadata<
2,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt32,
int32_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_Phase kPhase{};
void set_phase(int32_t value) {
static constexpr uint32_t field_id = FieldMetadata_Phase::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt32>
::Append(*this, field_id, value);
}
using FieldMetadata_DurationUs =
::protozero::proto_utils::FieldMetadata<
3,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_DurationUs kDurationUs{};
void set_duration_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_DurationUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadDurationUs =
::protozero::proto_utils::FieldMetadata<
4,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_ThreadDurationUs kThreadDurationUs{};
void set_thread_duration_us(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadDurationUs::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_ThreadInstructionDelta =
::protozero::proto_utils::FieldMetadata<
15,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt64,
int64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_ThreadInstructionDelta kThreadInstructionDelta{};
void set_thread_instruction_delta(int64_t value) {
static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionDelta::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt64>
::Append(*this, field_id, value);
}
using FieldMetadata_UnscopedId =
::protozero::proto_utils::FieldMetadata<
6,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_UnscopedId kUnscopedId{};
void set_unscoped_id(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_UnscopedId::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_LocalId =
::protozero::proto_utils::FieldMetadata<
10,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_LocalId kLocalId{};
void set_local_id(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_LocalId::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_GlobalId =
::protozero::proto_utils::FieldMetadata<
11,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_GlobalId kGlobalId{};
void set_global_id(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_GlobalId::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_IdScope =
::protozero::proto_utils::FieldMetadata<
7,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kString,
std::string,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_IdScope kIdScope{};
void set_id_scope(const char* data, size_t size) {
AppendBytes(FieldMetadata_IdScope::kFieldId, data, size);
}
void set_id_scope(::protozero::ConstChars chars) {
AppendBytes(FieldMetadata_IdScope::kFieldId, chars.data, chars.size);
}
void set_id_scope(std::string value) {
static constexpr uint32_t field_id = FieldMetadata_IdScope::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kString>
::Append(*this, field_id, value);
}
using FieldMetadata_UseAsyncTts =
::protozero::proto_utils::FieldMetadata<
9,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kBool,
bool,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_UseAsyncTts kUseAsyncTts{};
void set_use_async_tts(bool value) {
static constexpr uint32_t field_id = FieldMetadata_UseAsyncTts::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kBool>
::Append(*this, field_id, value);
}
using FieldMetadata_BindId =
::protozero::proto_utils::FieldMetadata<
8,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kUint64,
uint64_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_BindId kBindId{};
void set_bind_id(uint64_t value) {
static constexpr uint32_t field_id = FieldMetadata_BindId::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kUint64>
::Append(*this, field_id, value);
}
using FieldMetadata_BindToEnclosing =
::protozero::proto_utils::FieldMetadata<
12,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kBool,
bool,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_BindToEnclosing kBindToEnclosing{};
void set_bind_to_enclosing(bool value) {
static constexpr uint32_t field_id = FieldMetadata_BindToEnclosing::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kBool>
::Append(*this, field_id, value);
}
using FieldMetadata_FlowDirection =
::protozero::proto_utils::FieldMetadata<
13,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kEnum,
TrackEvent_LegacyEvent_FlowDirection,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_FlowDirection kFlowDirection{};
void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) {
static constexpr uint32_t field_id = FieldMetadata_FlowDirection::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kEnum>
::Append(*this, field_id, value);
}
using FieldMetadata_InstantEventScope =
::protozero::proto_utils::FieldMetadata<
14,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kEnum,
TrackEvent_LegacyEvent_InstantEventScope,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_InstantEventScope kInstantEventScope{};
void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) {
static constexpr uint32_t field_id = FieldMetadata_InstantEventScope::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kEnum>
::Append(*this, field_id, value);
}
using FieldMetadata_PidOverride =
::protozero::proto_utils::FieldMetadata<
18,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt32,
int32_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_PidOverride kPidOverride{};
void set_pid_override(int32_t value) {
static constexpr uint32_t field_id = FieldMetadata_PidOverride::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt32>
::Append(*this, field_id, value);
}
using FieldMetadata_TidOverride =
::protozero::proto_utils::FieldMetadata<
19,
::protozero::proto_utils::RepetitionType::kNotRepeated,
::protozero::proto_utils::ProtoSchemaType::kInt32,
int32_t,
TrackEvent_LegacyEvent>;
static constexpr FieldMetadata_TidOverride kTidOverride{};
void set_tid_override(int32_t value) {
static constexpr uint32_t field_id = FieldMetadata_TidOverride::kFieldId;
// Call the appropriate protozero::Message::Append(field_id, ...)
// method based on the type of the field.
::protozero::internal::FieldWriter<
::protozero::proto_utils::ProtoSchemaType::kInt32>
::Append(*this, field_id, value);
}
};
} // Namespace.
} // Namespace.
} // Namespace.
#endif // Include guard.
/*
* Copyright (C) 2020 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_TRACK_EVENT_STATE_TRACKER_H_
#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
#include <map>
#include <string>
#include <vector>
namespace perfetto {
namespace protos {
namespace pbzero {
class TracePacket_Decoder;
class TrackEvent;
class TrackEvent_Decoder;
} // namespace pbzero
} // namespace protos
// A helper for keeping track of incremental state when intercepting track
// events.
class PERFETTO_EXPORT_COMPONENT TrackEventStateTracker {
public:
~TrackEventStateTracker();
struct StackFrame {
uint64_t timestamp{};
// Only one of |name| and |name_iid| will be set.
std::string name;
uint64_t name_iid{};
uint64_t name_hash{};
// Only one of |category| and |category_iid| will be set.
std::string category;
uint64_t category_iid{};
};
struct Track {
uint64_t uuid{};
uint32_t index{}; // Ordinal number for the track in the tracing session.
std::string name;
int64_t pid{};
int64_t tid{};
// Opaque user data associated with the track.
std::vector<uint8_t> user_data;
// Stack of opened slices on this track.
std::vector<StackFrame> stack;
};
// State for a single trace writer sequence (typically a single thread).
struct SequenceState {
// Trace packet sequence defaults.
Track track;
// Interned state.
#if PERFETTO_DCHECK_IS_ON()
uint32_t sequence_id{};
#endif
std::map<uint64_t /*iid*/, std::string> event_names;
std::map<uint64_t /*iid*/, std::string> event_categories;
std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
// Current absolute timestamp of the incremental clock.
uint64_t most_recent_absolute_time_ns = 0;
// default_clock_id == 0 means, no default clock_id is set.
uint32_t default_clock_id = 0;
};
// State for the entire tracing session. Shared by all trace writer sequences
// participating in the session.
struct SessionState {
// Non-thread-bound tracks.
std::map<uint64_t /*uuid*/, Track> tracks;
};
// Represents a single decoded track event (without arguments).
struct ParsedTrackEvent {
explicit ParsedTrackEvent(
const perfetto::protos::pbzero::TrackEvent::Decoder&);
// Underlying event.
const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;
// Event metadata.
uint64_t timestamp_ns{};
uint64_t duration_ns{};
size_t stack_depth{};
protozero::ConstChars category{};
protozero::ConstChars name{};
uint64_t name_hash{};
};
// Interface used by the tracker to access tracing session and sequence state
// and to report parsed track events.
class PERFETTO_EXPORT_COMPONENT Delegate {
public:
virtual ~Delegate();
// Called to retrieve the session-global state shared by all sequences. The
// returned pointer must remain valid (locked) throughout the call to
// |ProcessTracePacket|.
virtual SessionState* GetSessionState() = 0;
// Called when the metadata (e.g., name) for a track changes. |Track| can be
// modified by the callback to attach user data.
virtual void OnTrackUpdated(Track&) = 0;
// If the packet given to |ProcessTracePacket| contains a track event, this
// method is called to report the properties of that event. Note that memory
// pointers in |TrackEvent| will only be valid during this call.
virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
};
// Process a single trace packet, reporting any contained track event back via
// the delegate interface. |SequenceState| must correspond to the sequence
// that was used to write the packet.
static void ProcessTracePacket(Delegate&,
SequenceState&,
const protos::pbzero::TracePacket_Decoder&);
private:
static void UpdateIncrementalState(
Delegate&,
SequenceState&,
const protos::pbzero::TracePacket_Decoder&);
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
/*
* Copyright (C) 2020 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_CONSOLE_INTERCEPTOR_H_
#define INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
#include <stdarg.h>
#include <functional>
#include <map>
#include <vector>
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <io.h>
#else
#include <unistd.h>
#endif
#if defined(__GNUC__) || defined(__clang__)
#define PERFETTO_PRINTF_ATTR \
__attribute__((format(printf, /*format_index=*/2, /*first_to_check=*/3)))
#else
#define PERFETTO_PRINTF_ATTR
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && !defined(STDOUT_FILENO)
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
namespace perfetto {
namespace protos {
namespace pbzero {
class DebugAnnotation_Decoder;
class TracePacket_Decoder;
class TrackEvent_Decoder;
} // namespace pbzero
} // namespace protos
struct ConsoleColor;
class PERFETTO_EXPORT_COMPONENT ConsoleInterceptor
: public Interceptor<ConsoleInterceptor> {
public:
~ConsoleInterceptor() override;
static void Register();
static void OnTracePacket(InterceptorContext context);
static void SetOutputFdForTesting(int fd);
void OnSetup(const SetupArgs&) override;
void OnStart(const StartArgs&) override;
void OnStop(const StopArgs&) override;
struct ThreadLocalState : public InterceptorBase::ThreadLocalState {
ThreadLocalState(ThreadLocalStateArgs&);
~ThreadLocalState() override;
// Destination file. Assumed to stay valid until the program ends (i.e., is
// stderr or stdout).
int fd{};
bool use_colors{};
// Messages up to this length are buffered and written atomically. If a
// message is longer, it will be printed with multiple writes.
std::array<char, 1024> message_buffer{};
size_t buffer_pos{};
// We only support a single trace writer sequence per thread, so the
// sequence state is stored in TLS.
TrackEventStateTracker::SequenceState sequence_state;
uint64_t start_time_ns{};
};
private:
class Delegate;
// Appends a formatted message to |message_buffer_| or directly to the output
// file if the buffer is full.
static void Printf(InterceptorContext& context,
const char* format,
...) PERFETTO_PRINTF_ATTR;
static void Flush(InterceptorContext& context);
static void SetColor(InterceptorContext& context, const ConsoleColor&);
static void SetColor(InterceptorContext& context, const char*);
static void PrintDebugAnnotations(InterceptorContext&,
const protos::pbzero::TrackEvent_Decoder&,
const ConsoleColor& slice_color,
const ConsoleColor& highlight_color);
static void PrintDebugAnnotationName(
InterceptorContext&,
const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
static void PrintDebugAnnotationValue(
InterceptorContext&,
const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
int fd_ = STDOUT_FILENO;
bool use_colors_ = true;
TrackEventStateTracker::SessionState session_state_;
uint64_t start_time_ns_{};
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_descriptor.h
// gen_amalgamated begin header: gen/protos/perfetto/common/data_source_descriptor.gen.h
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
#include <stdint.h>
#include <bitset>
#include <vector>
#include <string>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
namespace perfetto {
namespace protos {
namespace gen {
class DataSourceDescriptor;
} // namespace perfetto
} // namespace protos
} // namespace gen
namespace protozero {
class Message;
} // namespace protozero
namespace perfetto {
namespace protos {
namespace gen {
class PERFETTO_EXPORT_COMPONENT DataSourceDescriptor : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kNameFieldNumber = 1,
kIdFieldNumber = 7,
kWillNotifyOnStopFieldNumber = 2,
kWillNotifyOnStartFieldNumber = 3,
kHandlesIncrementalStateClearFieldNumber = 4,
kNoFlushFieldNumber = 9,
kGpuCounterDescriptorFieldNumber = 5,
kTrackEventDescriptorFieldNumber = 6,
kFtraceDescriptorFieldNumber = 8,
};
DataSourceDescriptor();
~DataSourceDescriptor() override;
DataSourceDescriptor(DataSourceDescriptor&&) noexcept;
DataSourceDescriptor& operator=(DataSourceDescriptor&&);
DataSourceDescriptor(const DataSourceDescriptor&);
DataSourceDescriptor& operator=(const DataSourceDescriptor&);
bool operator==(const DataSourceDescriptor&) const;
bool operator!=(const DataSourceDescriptor& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_name() const { return _has_field_[1]; }
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
bool has_id() const { return _has_field_[7]; }
uint64_t id() const { return id_; }
void set_id(uint64_t value) { id_ = value; _has_field_.set(7); }
bool has_will_notify_on_stop() const { return _has_field_[2]; }
bool will_notify_on_stop() const { return will_notify_on_stop_; }
void set_will_notify_on_stop(bool value) { will_notify_on_stop_ = value; _has_field_.set(2); }
bool has_will_notify_on_start() const { return _has_field_[3]; }
bool will_notify_on_start() const { return will_notify_on_start_; }
void set_will_notify_on_start(bool value) { will_notify_on_start_ = value; _has_field_.set(3); }
bool has_handles_incremental_state_clear() const { return _has_field_[4]; }
bool handles_incremental_state_clear() const { return handles_incremental_state_clear_; }
void set_handles_incremental_state_clear(bool value) { handles_incremental_state_clear_ = value; _has_field_.set(4); }
bool has_no_flush() const { return _has_field_[9]; }
bool no_flush() const { return no_flush_; }
void set_no_flush(bool value) { no_flush_ = value; _has_field_.set(9); }
const std::string& gpu_counter_descriptor_raw() const { return gpu_counter_descriptor_; }
void set_gpu_counter_descriptor_raw(const std::string& raw) { gpu_counter_descriptor_ = raw; _has_field_.set(5); }
const std::string& track_event_descriptor_raw() const { return track_event_descriptor_; }
void set_track_event_descriptor_raw(const std::string& raw) { track_event_descriptor_ = raw; _has_field_.set(6); }
const std::string& ftrace_descriptor_raw() const { return ftrace_descriptor_; }
void set_ftrace_descriptor_raw(const std::string& raw) { ftrace_descriptor_ = raw; _has_field_.set(8); }
private:
std::string name_{};
uint64_t id_{};
bool will_notify_on_stop_{};
bool will_notify_on_start_{};
bool handles_incremental_state_clear_{};
bool no_flush_{};
std::string gpu_counter_descriptor_; // [lazy=true]
std::string track_event_descriptor_; // [lazy=true]
std::string ftrace_descriptor_; // [lazy=true]
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<10> _has_field_{};
};
} // namespace perfetto
} // namespace protos
} // namespace gen
#endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_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_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
#endif // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
// gen_amalgamated begin header: include/perfetto/tracing/core/trace_config.h
// gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.gen.h
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
#include <stdint.h>
#include <bitset>
#include <vector>
#include <string>
#include <type_traits>
// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
namespace perfetto {
namespace protos {
namespace gen {
class TraceConfig;
class TraceConfig_SessionSemaphore;
class TraceConfig_CmdTraceStartDelay;
class TraceConfig_AndroidReportConfig;
class TraceConfig_TraceFilter;
class TraceConfig_TraceFilter_StringFilterChain;
class TraceConfig_TraceFilter_StringFilterRule;
class TraceConfig_IncidentReportConfig;
class TraceConfig_IncrementalStateConfig;
class TraceConfig_TriggerConfig;
class TraceConfig_TriggerConfig_Trigger;
class TraceConfig_GuardrailOverrides;
class TraceConfig_StatsdMetadata;
class TraceConfig_ProducerConfig;
class TraceConfig_BuiltinDataSource;
class TraceConfig_DataSource;
class DataSourceConfig;
class TestConfig;
class TestConfig_DummyFields;
class InterceptorConfig;
class ConsoleConfig;
class ChromeConfig;
class SystemInfoConfig;
class TraceConfig_BufferConfig;
enum TraceConfig_LockdownModeOperation : int;
enum TraceConfig_CompressionType : int;
enum TraceConfig_StatsdLogging : int;
enum TraceConfig_TraceFilter_StringFilterPolicy : int;
enum TraceConfig_TriggerConfig_TriggerMode : int;
enum BuiltinClock : int;
enum DataSourceConfig_SessionInitiator : int;
enum ConsoleConfig_Output : int;
enum ChromeConfig_ClientPriority : int;
enum TraceConfig_BufferConfig_FillPolicy : int;
} // namespace perfetto
} // namespace protos
} // namespace gen
namespace protozero {
class Message;
} // namespace protozero
namespace perfetto {
namespace protos {
namespace gen {
enum TraceConfig_LockdownModeOperation : int {
TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
};
enum TraceConfig_CompressionType : int {
TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
};
enum TraceConfig_StatsdLogging : int {
TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
};
enum TraceConfig_TraceFilter_StringFilterPolicy : int {
TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED = 0,
TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS = 1,
TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS = 2,
TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK = 3,
TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK = 4,
TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = 5,
};
enum TraceConfig_TriggerConfig_TriggerMode : int {
TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT = 4,
};
enum TraceConfig_BufferConfig_FillPolicy : int {
TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
};
class PERFETTO_EXPORT_COMPONENT TraceConfig : public ::protozero::CppMessageObj {
public:
using BufferConfig = TraceConfig_BufferConfig;
using DataSource = TraceConfig_DataSource;
using BuiltinDataSource = TraceConfig_BuiltinDataSource;
using ProducerConfig = TraceConfig_ProducerConfig;
using StatsdMetadata = TraceConfig_StatsdMetadata;
using GuardrailOverrides = TraceConfig_GuardrailOverrides;
using TriggerConfig = TraceConfig_TriggerConfig;
using IncrementalStateConfig = TraceConfig_IncrementalStateConfig;
using IncidentReportConfig = TraceConfig_IncidentReportConfig;
using TraceFilter = TraceConfig_TraceFilter;
using AndroidReportConfig = TraceConfig_AndroidReportConfig;
using CmdTraceStartDelay = TraceConfig_CmdTraceStartDelay;
using SessionSemaphore = TraceConfig_SessionSemaphore;
using LockdownModeOperation = TraceConfig_LockdownModeOperation;
static constexpr auto LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
static constexpr auto LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
static constexpr auto LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
static constexpr auto LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
static constexpr auto LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
using CompressionType = TraceConfig_CompressionType;
static constexpr auto COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
static constexpr auto COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
static constexpr auto CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
static constexpr auto CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
using StatsdLogging = TraceConfig_StatsdLogging;
static constexpr auto STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
static constexpr auto STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
static constexpr auto STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
static constexpr auto StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
static constexpr auto StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
enum FieldNumbers {
kBuffersFieldNumber = 1,
kDataSourcesFieldNumber = 2,
kBuiltinDataSourcesFieldNumber = 20,
kDurationMsFieldNumber = 3,
kPreferSuspendClockForDurationFieldNumber = 36,
kEnableExtraGuardrailsFieldNumber = 4,
kLockdownModeFieldNumber = 5,
kProducersFieldNumber = 6,
kStatsdMetadataFieldNumber = 7,
kWriteIntoFileFieldNumber = 8,
kOutputPathFieldNumber = 29,
kFileWritePeriodMsFieldNumber = 9,
kMaxFileSizeBytesFieldNumber = 10,
kGuardrailOverridesFieldNumber = 11,
kDeferredStartFieldNumber = 12,
kFlushPeriodMsFieldNumber = 13,
kFlushTimeoutMsFieldNumber = 14,
kDataSourceStopTimeoutMsFieldNumber = 23,
kNotifyTraceurFieldNumber = 16,
kBugreportScoreFieldNumber = 30,
kBugreportFilenameFieldNumber = 38,
kTriggerConfigFieldNumber = 17,
kActivateTriggersFieldNumber = 18,
kIncrementalStateConfigFieldNumber = 21,
kAllowUserBuildTracingFieldNumber = 19,
kUniqueSessionNameFieldNumber = 22,
kCompressionTypeFieldNumber = 24,
kIncidentReportConfigFieldNumber = 25,
kStatsdLoggingFieldNumber = 31,
kTraceUuidMsbFieldNumber = 27,
kTraceUuidLsbFieldNumber = 28,
kTraceFilterFieldNumber = 33,
kAndroidReportConfigFieldNumber = 34,
kCmdTraceStartDelayFieldNumber = 35,
kSessionSemaphoresFieldNumber = 39,
};
TraceConfig();
~TraceConfig() override;
TraceConfig(TraceConfig&&) noexcept;
TraceConfig& operator=(TraceConfig&&);
TraceConfig(const TraceConfig&);
TraceConfig& operator=(const TraceConfig&);
bool operator==(const TraceConfig&) const;
bool operator!=(const TraceConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
const std::vector<TraceConfig_BufferConfig>& buffers() const { return buffers_; }
std::vector<TraceConfig_BufferConfig>* mutable_buffers() { return &buffers_; }
int buffers_size() const;
void clear_buffers();
TraceConfig_BufferConfig* add_buffers();
const std::vector<TraceConfig_DataSource>& data_sources() const { return data_sources_; }
std::vector<TraceConfig_DataSource>* mutable_data_sources() { return &data_sources_; }
int data_sources_size() const;
void clear_data_sources();
TraceConfig_DataSource* add_data_sources();
bool has_builtin_data_sources() const { return _has_field_[20]; }
const TraceConfig_BuiltinDataSource& builtin_data_sources() const { return *builtin_data_sources_; }
TraceConfig_BuiltinDataSource* mutable_builtin_data_sources() { _has_field_.set(20); return builtin_data_sources_.get(); }
bool has_duration_ms() const { return _has_field_[3]; }
uint32_t duration_ms() const { return duration_ms_; }
void set_duration_ms(uint32_t value) { duration_ms_ = value; _has_field_.set(3); }
bool has_prefer_suspend_clock_for_duration() const { return _has_field_[36]; }
bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(36); }
bool has_enable_extra_guardrails() const { return _has_field_[4]; }
bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(4); }
bool has_lockdown_mode() const { return _has_field_[5]; }
TraceConfig_LockdownModeOperation lockdown_mode() const { return lockdown_mode_; }
void set_lockdown_mode(TraceConfig_LockdownModeOperation value) { lockdown_mode_ = value; _has_field_.set(5); }
const std::vector<TraceConfig_ProducerConfig>& producers() const { return producers_; }
std::vector<TraceConfig_ProducerConfig>* mutable_producers() { return &producers_; }
int producers_size() const;
void clear_producers();
TraceConfig_ProducerConfig* add_producers();
bool has_statsd_metadata() const { return _has_field_[7]; }
const TraceConfig_StatsdMetadata& statsd_metadata() const { return *statsd_metadata_; }
TraceConfig_StatsdMetadata* mutable_statsd_metadata() { _has_field_.set(7); return statsd_metadata_.get(); }
bool has_write_into_file() const { return _has_field_[8]; }
bool write_into_file() const { return write_into_file_; }
void set_write_into_file(bool value) { write_into_file_ = value; _has_field_.set(8); }
bool has_output_path() const { return _has_field_[29]; }
const std::string& output_path() const { return output_path_; }
void set_output_path(const std::string& value) { output_path_ = value; _has_field_.set(29); }
bool has_file_write_period_ms() const { return _has_field_[9]; }
uint32_t file_write_period_ms() const { return file_write_period_ms_; }
void set_file_write_period_ms(uint32_t value) { file_write_period_ms_ = value; _has_field_.set(9); }
bool has_max_file_size_bytes() const { return _has_field_[10]; }
uint64_t max_file_size_bytes() const { return max_file_size_bytes_; }
void set_max_file_size_bytes(uint64_t value) { max_file_size_bytes_ = value; _has_field_.set(10); }
bool has_guardrail_overrides() const { return _has_field_[11]; }
const TraceConfig_GuardrailOverrides& guardrail_overrides() const { return *guardrail_overrides_; }
TraceConfig_GuardrailOverrides* mutable_guardrail_overrides() { _has_field_.set(11); return guardrail_overrides_.get(); }
bool has_deferred_start() const { return _has_field_[12]; }
bool deferred_start() const { return deferred_start_; }
void set_deferred_start(bool value) { deferred_start_ = value; _has_field_.set(12); }
bool has_flush_period_ms() const { return _has_field_[13]; }
uint32_t flush_period_ms() const { return flush_period_ms_; }
void set_flush_period_ms(uint32_t value) { flush_period_ms_ = value; _has_field_.set(13); }
bool has_flush_timeout_ms() const { return _has_field_[14]; }
uint32_t flush_timeout_ms() const { return flush_timeout_ms_; }
void set_flush_timeout_ms(uint32_t value) { flush_timeout_ms_ = value; _has_field_.set(14); }
bool has_data_source_stop_timeout_ms() const { return _has_field_[23]; }
uint32_t data_source_stop_timeout_ms() const { return data_source_stop_timeout_ms_; }
void set_data_source_stop_timeout_ms(uint32_t value) { data_source_stop_timeout_ms_ = value; _has_field_.set(23); }
bool has_notify_traceur() const { return _has_field_[16]; }
bool notify_traceur() const { return notify_traceur_; }
void set_notify_traceur(bool value) { notify_traceur_ = value; _has_field_.set(16); }
bool has_bugreport_score() const { return _has_field_[30]; }
int32_t bugreport_score() const { return bugreport_score_; }
void set_bugreport_score(int32_t value) { bugreport_score_ = value; _has_field_.set(30); }
bool has_bugreport_filename() const { return _has_field_[38]; }
const std::string& bugreport_filename() const { return bugreport_filename_; }
void set_bugreport_filename(const std::string& value) { bugreport_filename_ = value; _has_field_.set(38); }
bool has_trigger_config() const { return _has_field_[17]; }
const TraceConfig_TriggerConfig& trigger_config() const { return *trigger_config_; }
TraceConfig_TriggerConfig* mutable_trigger_config() { _has_field_.set(17); return trigger_config_.get(); }
const std::vector<std::string>& activate_triggers() const { return activate_triggers_; }
std::vector<std::string>* mutable_activate_triggers() { return &activate_triggers_; }
int activate_triggers_size() const { return static_cast<int>(activate_triggers_.size()); }
void clear_activate_triggers() { activate_triggers_.clear(); }
void add_activate_triggers(std::string value) { activate_triggers_.emplace_back(value); }
std::string* add_activate_triggers() { activate_triggers_.emplace_back(); return &activate_triggers_.back(); }
bool has_incremental_state_config() const { return _has_field_[21]; }
const TraceConfig_IncrementalStateConfig& incremental_state_config() const { return *incremental_state_config_; }
TraceConfig_IncrementalStateConfig* mutable_incremental_state_config() { _has_field_.set(21); return incremental_state_config_.get(); }
bool has_allow_user_build_tracing() const { return _has_field_[19]; }
bool allow_user_build_tracing() const { return allow_user_build_tracing_; }
void set_allow_user_build_tracing(bool value) { allow_user_build_tracing_ = value; _has_field_.set(19); }
bool has_unique_session_name() const { return _has_field_[22]; }
const std::string& unique_session_name() const { return unique_session_name_; }
void set_unique_session_name(const std::string& value) { unique_session_name_ = value; _has_field_.set(22); }
bool has_compression_type() const { return _has_field_[24]; }
TraceConfig_CompressionType compression_type() const { return compression_type_; }
void set_compression_type(TraceConfig_CompressionType value) { compression_type_ = value; _has_field_.set(24); }
bool has_incident_report_config() const { return _has_field_[25]; }
const TraceConfig_IncidentReportConfig& incident_report_config() const { return *incident_report_config_; }
TraceConfig_IncidentReportConfig* mutable_incident_report_config() { _has_field_.set(25); return incident_report_config_.get(); }
bool has_statsd_logging() const { return _has_field_[31]; }
TraceConfig_StatsdLogging statsd_logging() const { return statsd_logging_; }
void set_statsd_logging(TraceConfig_StatsdLogging value) { statsd_logging_ = value; _has_field_.set(31); }
bool has_trace_uuid_msb() const { return _has_field_[27]; }
int64_t trace_uuid_msb() const { return trace_uuid_msb_; }
void set_trace_uuid_msb(int64_t value) { trace_uuid_msb_ = value; _has_field_.set(27); }
bool has_trace_uuid_lsb() const { return _has_field_[28]; }
int64_t trace_uuid_lsb() const { return trace_uuid_lsb_; }
void set_trace_uuid_lsb(int64_t value) { trace_uuid_lsb_ = value; _has_field_.set(28); }
bool has_trace_filter() const { return _has_field_[33]; }
const TraceConfig_TraceFilter& trace_filter() const { return *trace_filter_; }
TraceConfig_TraceFilter* mutable_trace_filter() { _has_field_.set(33); return trace_filter_.get(); }
bool has_android_report_config() const { return _has_field_[34]; }
const TraceConfig_AndroidReportConfig& android_report_config() const { return *android_report_config_; }
TraceConfig_AndroidReportConfig* mutable_android_report_config() { _has_field_.set(34); return android_report_config_.get(); }
bool has_cmd_trace_start_delay() const { return _has_field_[35]; }
const TraceConfig_CmdTraceStartDelay& cmd_trace_start_delay() const { return *cmd_trace_start_delay_; }
TraceConfig_CmdTraceStartDelay* mutable_cmd_trace_start_delay() { _has_field_.set(35); return cmd_trace_start_delay_.get(); }
const std::vector<TraceConfig_SessionSemaphore>& session_semaphores() const { return session_semaphores_; }
std::vector<TraceConfig_SessionSemaphore>* mutable_session_semaphores() { return &session_semaphores_; }
int session_semaphores_size() const;
void clear_session_semaphores();
TraceConfig_SessionSemaphore* add_session_semaphores();
private:
std::vector<TraceConfig_BufferConfig> buffers_;
std::vector<TraceConfig_DataSource> data_sources_;
::protozero::CopyablePtr<TraceConfig_BuiltinDataSource> builtin_data_sources_;
uint32_t duration_ms_{};
bool prefer_suspend_clock_for_duration_{};
bool enable_extra_guardrails_{};
TraceConfig_LockdownModeOperation lockdown_mode_{};
std::vector<TraceConfig_ProducerConfig> producers_;
::protozero::CopyablePtr<TraceConfig_StatsdMetadata> statsd_metadata_;
bool write_into_file_{};
std::string output_path_{};
uint32_t file_write_period_ms_{};
uint64_t max_file_size_bytes_{};
::protozero::CopyablePtr<TraceConfig_GuardrailOverrides> guardrail_overrides_;
bool deferred_start_{};
uint32_t flush_period_ms_{};
uint32_t flush_timeout_ms_{};
uint32_t data_source_stop_timeout_ms_{};
bool notify_traceur_{};
int32_t bugreport_score_{};
std::string bugreport_filename_{};
::protozero::CopyablePtr<TraceConfig_TriggerConfig> trigger_config_;
std::vector<std::string> activate_triggers_;
::protozero::CopyablePtr<TraceConfig_IncrementalStateConfig> incremental_state_config_;
bool allow_user_build_tracing_{};
std::string unique_session_name_{};
TraceConfig_CompressionType compression_type_{};
::protozero::CopyablePtr<TraceConfig_IncidentReportConfig> incident_report_config_;
TraceConfig_StatsdLogging statsd_logging_{};
int64_t trace_uuid_msb_{};
int64_t trace_uuid_lsb_{};
::protozero::CopyablePtr<TraceConfig_TraceFilter> trace_filter_;
::protozero::CopyablePtr<TraceConfig_AndroidReportConfig> android_report_config_;
::protozero::CopyablePtr<TraceConfig_CmdTraceStartDelay> cmd_trace_start_delay_;
std::vector<TraceConfig_SessionSemaphore> session_semaphores_;
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<40> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_SessionSemaphore : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kNameFieldNumber = 1,
kMaxOtherSessionCountFieldNumber = 2,
};
TraceConfig_SessionSemaphore();
~TraceConfig_SessionSemaphore() override;
TraceConfig_SessionSemaphore(TraceConfig_SessionSemaphore&&) noexcept;
TraceConfig_SessionSemaphore& operator=(TraceConfig_SessionSemaphore&&);
TraceConfig_SessionSemaphore(const TraceConfig_SessionSemaphore&);
TraceConfig_SessionSemaphore& operator=(const TraceConfig_SessionSemaphore&);
bool operator==(const TraceConfig_SessionSemaphore&) const;
bool operator!=(const TraceConfig_SessionSemaphore& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_name() const { return _has_field_[1]; }
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
bool has_max_other_session_count() const { return _has_field_[2]; }
uint64_t max_other_session_count() const { return max_other_session_count_; }
void set_max_other_session_count(uint64_t value) { max_other_session_count_ = value; _has_field_.set(2); }
private:
std::string name_{};
uint64_t max_other_session_count_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<3> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_CmdTraceStartDelay : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kMinDelayMsFieldNumber = 1,
kMaxDelayMsFieldNumber = 2,
};
TraceConfig_CmdTraceStartDelay();
~TraceConfig_CmdTraceStartDelay() override;
TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept;
TraceConfig_CmdTraceStartDelay& operator=(TraceConfig_CmdTraceStartDelay&&);
TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&);
TraceConfig_CmdTraceStartDelay& operator=(const TraceConfig_CmdTraceStartDelay&);
bool operator==(const TraceConfig_CmdTraceStartDelay&) const;
bool operator!=(const TraceConfig_CmdTraceStartDelay& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_min_delay_ms() const { return _has_field_[1]; }
uint32_t min_delay_ms() const { return min_delay_ms_; }
void set_min_delay_ms(uint32_t value) { min_delay_ms_ = value; _has_field_.set(1); }
bool has_max_delay_ms() const { return _has_field_[2]; }
uint32_t max_delay_ms() const { return max_delay_ms_; }
void set_max_delay_ms(uint32_t value) { max_delay_ms_ = value; _has_field_.set(2); }
private:
uint32_t min_delay_ms_{};
uint32_t max_delay_ms_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<3> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_AndroidReportConfig : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kReporterServicePackageFieldNumber = 1,
kReporterServiceClassFieldNumber = 2,
kSkipReportFieldNumber = 3,
kUsePipeInFrameworkForTestingFieldNumber = 4,
};
TraceConfig_AndroidReportConfig();
~TraceConfig_AndroidReportConfig() override;
TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept;
TraceConfig_AndroidReportConfig& operator=(TraceConfig_AndroidReportConfig&&);
TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&);
TraceConfig_AndroidReportConfig& operator=(const TraceConfig_AndroidReportConfig&);
bool operator==(const TraceConfig_AndroidReportConfig&) const;
bool operator!=(const TraceConfig_AndroidReportConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_reporter_service_package() const { return _has_field_[1]; }
const std::string& reporter_service_package() const { return reporter_service_package_; }
void set_reporter_service_package(const std::string& value) { reporter_service_package_ = value; _has_field_.set(1); }
bool has_reporter_service_class() const { return _has_field_[2]; }
const std::string& reporter_service_class() const { return reporter_service_class_; }
void set_reporter_service_class(const std::string& value) { reporter_service_class_ = value; _has_field_.set(2); }
bool has_skip_report() const { return _has_field_[3]; }
bool skip_report() const { return skip_report_; }
void set_skip_report(bool value) { skip_report_ = value; _has_field_.set(3); }
bool has_use_pipe_in_framework_for_testing() const { return _has_field_[4]; }
bool use_pipe_in_framework_for_testing() const { return use_pipe_in_framework_for_testing_; }
void set_use_pipe_in_framework_for_testing(bool value) { use_pipe_in_framework_for_testing_ = value; _has_field_.set(4); }
private:
std::string reporter_service_package_{};
std::string reporter_service_class_{};
bool skip_report_{};
bool use_pipe_in_framework_for_testing_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<5> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter : public ::protozero::CppMessageObj {
public:
using StringFilterRule = TraceConfig_TraceFilter_StringFilterRule;
using StringFilterChain = TraceConfig_TraceFilter_StringFilterChain;
using StringFilterPolicy = TraceConfig_TraceFilter_StringFilterPolicy;
static constexpr auto SFP_UNSPECIFIED = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
static constexpr auto SFP_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS;
static constexpr auto SFP_ATRACE_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS;
static constexpr auto SFP_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK;
static constexpr auto SFP_ATRACE_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK;
static constexpr auto SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
static constexpr auto StringFilterPolicy_MIN = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
static constexpr auto StringFilterPolicy_MAX = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
enum FieldNumbers {
kBytecodeFieldNumber = 1,
kBytecodeV2FieldNumber = 2,
kStringFilterChainFieldNumber = 3,
};
TraceConfig_TraceFilter();
~TraceConfig_TraceFilter() override;
TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept;
TraceConfig_TraceFilter& operator=(TraceConfig_TraceFilter&&);
TraceConfig_TraceFilter(const TraceConfig_TraceFilter&);
TraceConfig_TraceFilter& operator=(const TraceConfig_TraceFilter&);
bool operator==(const TraceConfig_TraceFilter&) const;
bool operator!=(const TraceConfig_TraceFilter& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_bytecode() const { return _has_field_[1]; }
const std::string& bytecode() const { return bytecode_; }
void set_bytecode(const std::string& value) { bytecode_ = value; _has_field_.set(1); }
void set_bytecode(const void* p, size_t s) { bytecode_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
bool has_bytecode_v2() const { return _has_field_[2]; }
const std::string& bytecode_v2() const { return bytecode_v2_; }
void set_bytecode_v2(const std::string& value) { bytecode_v2_ = value; _has_field_.set(2); }
void set_bytecode_v2(const void* p, size_t s) { bytecode_v2_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
bool has_string_filter_chain() const { return _has_field_[3]; }
const TraceConfig_TraceFilter_StringFilterChain& string_filter_chain() const { return *string_filter_chain_; }
TraceConfig_TraceFilter_StringFilterChain* mutable_string_filter_chain() { _has_field_.set(3); return string_filter_chain_.get(); }
private:
std::string bytecode_{};
std::string bytecode_v2_{};
::protozero::CopyablePtr<TraceConfig_TraceFilter_StringFilterChain> string_filter_chain_;
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<4> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterChain : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kRulesFieldNumber = 1,
};
TraceConfig_TraceFilter_StringFilterChain();
~TraceConfig_TraceFilter_StringFilterChain() override;
TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept;
TraceConfig_TraceFilter_StringFilterChain& operator=(TraceConfig_TraceFilter_StringFilterChain&&);
TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&);
TraceConfig_TraceFilter_StringFilterChain& operator=(const TraceConfig_TraceFilter_StringFilterChain&);
bool operator==(const TraceConfig_TraceFilter_StringFilterChain&) const;
bool operator!=(const TraceConfig_TraceFilter_StringFilterChain& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
const std::vector<TraceConfig_TraceFilter_StringFilterRule>& rules() const { return rules_; }
std::vector<TraceConfig_TraceFilter_StringFilterRule>* mutable_rules() { return &rules_; }
int rules_size() const;
void clear_rules();
TraceConfig_TraceFilter_StringFilterRule* add_rules();
private:
std::vector<TraceConfig_TraceFilter_StringFilterRule> rules_;
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<2> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterRule : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kPolicyFieldNumber = 1,
kRegexPatternFieldNumber = 2,
kAtracePayloadStartsWithFieldNumber = 3,
};
TraceConfig_TraceFilter_StringFilterRule();
~TraceConfig_TraceFilter_StringFilterRule() override;
TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept;
TraceConfig_TraceFilter_StringFilterRule& operator=(TraceConfig_TraceFilter_StringFilterRule&&);
TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&);
TraceConfig_TraceFilter_StringFilterRule& operator=(const TraceConfig_TraceFilter_StringFilterRule&);
bool operator==(const TraceConfig_TraceFilter_StringFilterRule&) const;
bool operator!=(const TraceConfig_TraceFilter_StringFilterRule& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_policy() const { return _has_field_[1]; }
TraceConfig_TraceFilter_StringFilterPolicy policy() const { return policy_; }
void set_policy(TraceConfig_TraceFilter_StringFilterPolicy value) { policy_ = value; _has_field_.set(1); }
bool has_regex_pattern() const { return _has_field_[2]; }
const std::string& regex_pattern() const { return regex_pattern_; }
void set_regex_pattern(const std::string& value) { regex_pattern_ = value; _has_field_.set(2); }
bool has_atrace_payload_starts_with() const { return _has_field_[3]; }
const std::string& atrace_payload_starts_with() const { return atrace_payload_starts_with_; }
void set_atrace_payload_starts_with(const std::string& value) { atrace_payload_starts_with_ = value; _has_field_.set(3); }
private:
TraceConfig_TraceFilter_StringFilterPolicy policy_{};
std::string regex_pattern_{};
std::string atrace_payload_starts_with_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<4> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_IncidentReportConfig : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kDestinationPackageFieldNumber = 1,
kDestinationClassFieldNumber = 2,
kPrivacyLevelFieldNumber = 3,
kSkipIncidentdFieldNumber = 5,
kSkipDropboxFieldNumber = 4,
};
TraceConfig_IncidentReportConfig();
~TraceConfig_IncidentReportConfig() override;
TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept;
TraceConfig_IncidentReportConfig& operator=(TraceConfig_IncidentReportConfig&&);
TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&);
TraceConfig_IncidentReportConfig& operator=(const TraceConfig_IncidentReportConfig&);
bool operator==(const TraceConfig_IncidentReportConfig&) const;
bool operator!=(const TraceConfig_IncidentReportConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_destination_package() const { return _has_field_[1]; }
const std::string& destination_package() const { return destination_package_; }
void set_destination_package(const std::string& value) { destination_package_ = value; _has_field_.set(1); }
bool has_destination_class() const { return _has_field_[2]; }
const std::string& destination_class() const { return destination_class_; }
void set_destination_class(const std::string& value) { destination_class_ = value; _has_field_.set(2); }
bool has_privacy_level() const { return _has_field_[3]; }
int32_t privacy_level() const { return privacy_level_; }
void set_privacy_level(int32_t value) { privacy_level_ = value; _has_field_.set(3); }
bool has_skip_incidentd() const { return _has_field_[5]; }
bool skip_incidentd() const { return skip_incidentd_; }
void set_skip_incidentd(bool value) { skip_incidentd_ = value; _has_field_.set(5); }
bool has_skip_dropbox() const { return _has_field_[4]; }
bool skip_dropbox() const { return skip_dropbox_; }
void set_skip_dropbox(bool value) { skip_dropbox_ = value; _has_field_.set(4); }
private:
std::string destination_package_{};
std::string destination_class_{};
int32_t privacy_level_{};
bool skip_incidentd_{};
bool skip_dropbox_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<6> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_IncrementalStateConfig : public ::protozero::CppMessageObj {
public:
enum FieldNumbers {
kClearPeriodMsFieldNumber = 1,
};
TraceConfig_IncrementalStateConfig();
~TraceConfig_IncrementalStateConfig() override;
TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept;
TraceConfig_IncrementalStateConfig& operator=(TraceConfig_IncrementalStateConfig&&);
TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&);
TraceConfig_IncrementalStateConfig& operator=(const TraceConfig_IncrementalStateConfig&);
bool operator==(const TraceConfig_IncrementalStateConfig&) const;
bool operator!=(const TraceConfig_IncrementalStateConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_clear_period_ms() const { return _has_field_[1]; }
uint32_t clear_period_ms() const { return clear_period_ms_; }
void set_clear_period_ms(uint32_t value) { clear_period_ms_ = value; _has_field_.set(1); }
private:
uint32_t clear_period_ms_{};
// Allows to preserve unknown protobuf fields for compatibility
// with future versions of .proto files.
std::string unknown_fields_;
std::bitset<2> _has_field_{};
};
class PERFETTO_EXPORT_COMPONENT TraceConfig_TriggerConfig : public ::protozero::CppMessageObj {
public:
using Trigger = TraceConfig_TriggerConfig_Trigger;
using TriggerMode = TraceConfig_TriggerConfig_TriggerMode;
static constexpr auto UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
static constexpr auto START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
static constexpr auto STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
static constexpr auto CLONE_SNAPSHOT = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
static constexpr auto TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
static constexpr auto TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
enum FieldNumbers {
kTriggerModeFieldNumber = 1,
kUseCloneSnapshotIfAvailableFieldNumber = 5,
kTriggersFieldNumber = 2,
kTriggerTimeoutMsFieldNumber = 3,
};
TraceConfig_TriggerConfig();
~TraceConfig_TriggerConfig() override;
TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept;
TraceConfig_TriggerConfig& operator=(TraceConfig_TriggerConfig&&);
TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&);
TraceConfig_TriggerConfig& operator=(const TraceConfig_TriggerConfig&);
bool operator==(const TraceConfig_TriggerConfig&) const;
bool operator!=(const TraceConfig_TriggerConfig& other) const { return !(*this == other); }
bool ParseFromArray(const void*, size_t) override;
std::string SerializeAsString() const override;
std::vector<uint8_t> SerializeAsArray() const override;
void Serialize(::protozero::Message*) const;
bool has_trigger_mode() const { return _has_field_[1]; }
TraceConfig_TriggerConfig_TriggerMode trigger_mode() const { return trigger_mode_; }
void set_trigger_mode(TraceConfig_TriggerConfig_TriggerMode value) { trigger_mode_ = value; _has_field_.set(1); }