chromium/third_party/perfetto/include/perfetto/tracing/internal/track_event_data_source.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_TRACK_EVENT_DATA_SOURCE_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_

#include "perfetto/base/compiler.h"
#include "perfetto/base/template_util.h"
#include "perfetto/protozero/message_handle.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/data_source.h"
#include "perfetto/tracing/event_context.h"
#include "perfetto/tracing/internal/track_event_internal.h"
#include "perfetto/tracing/internal/track_event_legacy.h"
#include "perfetto/tracing/internal/write_track_event_args.h"
#include "perfetto/tracing/track.h"
#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/common/builtin_clock.pbzero.h"
#include "protos/perfetto/config/track_event/track_event_config.gen.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"

#include <type_traits>

namespace perfetto {

namespace {

class StopArgsImpl : public DataSourceBase::StopArgs {};

}  // namespace

// A function for converting an abstract timestamp into a
// perfetto::TraceTimestamp struct. By specialising this template and defining
// static ConvertTimestampToTraceTimeNs function in it the user can register
// additional timestamp types. The return value should specify the
// clock domain used by the timestamp as well as its value.
//
// The supported clock domains are the ones described in
// perfetto.protos.ClockSnapshot. However, custom clock IDs (>=64) are
// reserved for internal use by the SDK for the time being.
// The timestamp value should be in nanoseconds regardless of the clock domain.
template <typename T>
struct TraceTimestampTraits;

// A pass-through implementation for raw uint64_t nanosecond timestamps.
template <>
struct TraceTimestampTraits<uint64_t> {};

// A pass-through implementation for the trace timestamp structure.
template <>
struct TraceTimestampTraits<TraceTimestamp> {};

namespace internal {
namespace {

// Checks if |T| is a valid track.
template <typename T>
static constexpr bool IsValidTrack() {}

// Checks if |T| is a valid non-counter track.
template <typename T>
static constexpr bool IsValidNormalTrack() {}

// Because the user can use arbitrary timestamp types, we can't compare against
// any known base type here. Instead, we check that a track or a trace lambda
// isn't being interpreted as a timestamp.
template <
    typename T,
    typename CanBeConvertedToNsCheck =
        decltype(::perfetto::TraceTimestampTraits<typename base::remove_cvref_t<
                     T>>::ConvertTimestampToTraceTimeNs(std::declval<T>())),
    typename NotTrackCheck =
        typename std::enable_if<!IsValidNormalTrack<T>()>::type,
    typename NotLambdaCheck =
        typename std::enable_if<!IsValidTraceLambda<T>()>::type>
static constexpr bool IsValidTimestamp() {}

// Taken from C++17
void_t;

// Returns true iff `GetStaticString(T)` is defined OR T == DynamicString.
template <typename T, typename = void>
struct IsValidEventNameType
    : std::is_same<perfetto::DynamicString, typename std::decay<T>::type> {};

IsValidEventNameType<T, void_t<decltype(GetStaticString(std::declval<T>()))>>;

template <typename T>
inline void ValidateEventNameType() {}

inline bool UnorderedEqual(std::vector<std::string> vec1,
                           std::vector<std::string> vec2) {}

}  // namespace

inline ::perfetto::DynamicString DecayEventNameType(
    ::perfetto::DynamicString name) {}

inline ::perfetto::StaticString DecayEventNameType(
    ::perfetto::StaticString name) {}

// Convert all static strings of different length to StaticString to avoid
// unnecessary template instantiations.
inline ::perfetto::StaticString DecayEventNameType(const char* name) {}

// Traits for dynamic categories.
template <typename CategoryType>
struct CategoryTraits {};

// Traits for static categories.
template <>
struct CategoryTraits<size_t> {};

struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {};

// A generic track event data source which is instantiated once per track event
// category namespace.
template <typename DerivedDataSource,
          const TrackEventCategoryRegistry* Registry>
class TrackEventDataSource
    : public DataSource<DerivedDataSource, TrackEventDataSourceTraits> {};

}  // namespace internal
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_