blob: d2b275f113720e30f10e778ec5d0d453b2ffac96 [file] [log] [blame] [edit]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// IWYU pragma: private, include "src/storage/lib/trace/trace.h"
#ifndef SRC_STORAGE_LIB_TRACE_TRACE_DISABLED_H_
#define SRC_STORAGE_LIB_TRACE_TRACE_DISABLED_H_
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <fbl/string_traits.h>
namespace storage::trace {
namespace internal {
template <typename T>
inline constexpr bool is_bool_v = std::is_same_v<T, bool>;
template <typename T, typename Enable = void>
struct TraceArg;
template <>
struct TraceArg<std::nullptr_t> {
static void Accept(std::nullptr_t arg) {}
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<is_bool_v<T>>> {
static void Accept(bool arg) {}
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<std::is_signed_v<T> && std::is_integral_v<T> &&
(sizeof(T) <= sizeof(int32_t))>> {
static void Accept(int32_t arg) {}
};
template <typename T>
struct TraceArg<T,
typename std::enable_if_t<!is_bool_v<T> && std::is_unsigned_v<T> &&
!std::is_enum_v<T> && (sizeof(T) <= sizeof(uint32_t))>> {
static void Accept(uint32_t arg) {}
};
template <typename T>
struct TraceArg<
T, typename std::enable_if_t<std::is_signed_v<T> && std::is_integral_v<T> &&
(sizeof(T) > sizeof(int32_t)) && (sizeof(T) <= sizeof(int64_t))>> {
static void Accept(int64_t arg) {}
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<std::is_unsigned_v<T> && !std::is_enum_v<T> &&
(sizeof(T) > sizeof(uint32_t)) &&
(sizeof(T) <= sizeof(uint64_t))>> {
static void Accept(uint64_t arg) {}
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<std::is_enum_v<T>>> {
using UnderlyingType = std::underlying_type_t<T>;
static void Accept(UnderlyingType arg) { TraceArg<UnderlyingType>::Accept(arg); }
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<std::is_floating_point_v<T>>> {
static void Accept(double arg) {}
};
template <size_t ArgSize>
struct TraceArg<char[ArgSize]> {
static void Accept(const char* arg) {}
};
template <typename T>
struct TraceArg<T, typename std::enable_if_t<fbl::is_string_like_v<T>>> {
static void Accept(const T& arg) {}
};
template <typename T>
struct TraceArg<T*> {
static void Accept(const T* arg) {}
};
// Base case for the recursive variadic template expansion.
inline void TraceArgs() {}
// Ensures that all of the argument names are string literals and all of the argument types will be
// accepted by the real tracing library.
template <size_t NameSize, typename Arg, typename... Args>
inline void TraceArgs(const char (&name)[NameSize], const Arg& arg, Args&&... args) {
TraceArg<Arg>::Accept(arg);
TraceArgs(std::forward<Args>(args)...);
}
// Mimics the type checking done on the real duration macros to ensure that code written without
// tracing enabled will compile when tracing is enabled.
template <size_t CategorySize, size_t NameSize, typename... Args>
inline void TraceDuration(const char (&category)[CategorySize], const char (&name)[NameSize],
Args&&... args) {
TraceArgs(std::forward<Args>(args)...);
}
// Mimics the type checking done on the real flow macros to ensure that code written without tracing
// enabled will compile when tracing is enabled.
template <size_t CategorySize, size_t NameSize, typename... Args>
inline void TraceFlow(const char (&category)[CategorySize], const char (&name)[NameSize],
uint64_t flow_id, Args&&... args) {
TraceArgs(std::forward<Args>(args)...);
}
} // namespace internal
// Generates a trace ID that will be unique across the system (barring overflow of the per-process
// nonce, reuse of a zx_handle_t for two processes, or some other code in this process which uses
// the same procedure to generate IDs).
//
// We use this instead of the standard TRACE_NONCE because TRACE_NONCE is only unique within a
// process; we need IDs that are unique across all processes.
inline uint64_t GenerateTraceId() { return 0; }
} // namespace storage::trace
#define TRACE_DURATION(category, name, ...) \
::storage::trace::internal::TraceDuration(category, name, ##__VA_ARGS__)
#define TRACE_DURATION_BEGIN(category, name, ...) \
::storage::trace::internal::TraceDuration(category, name, ##__VA_ARGS__)
#define TRACE_DURATION_END(category, name, ...) \
::storage::trace::internal::TraceDuration(category, name, ##__VA_ARGS__)
#define TRACE_FLOW_BEGIN(category, name, flow_id, ...) \
::storage::trace::internal::TraceFlow(category, name, flow_id, ##__VA_ARGS__)
#define TRACE_FLOW_STEP(category, name, flow_id, ...) \
::storage::trace::internal::TraceFlow(category, name, flow_id, ##__VA_ARGS__)
#define TRACE_FLOW_END(category, name, flow_id, ...) \
::storage::trace::internal::TraceFlow(category, name, flow_id, ##__VA_ARGS__)
#define TRACE_NONCE() 0
inline uint64_t GenerateTraceId() { return 0; }
#endif // SRC_STORAGE_LIB_TRACE_TRACE_DISABLED_H_