blob: 5ebf8a4da873069c7c80dc6f269555f22ca8eb5b [file] [log] [blame]
/*
* 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_MACROS_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
// This file contains underlying macros for the trace point track event
// implementation. Perfetto API users typically don't need to use anything here
// directly.
#include "perfetto/base/compiler.h"
#include "perfetto/tracing/internal/track_event_data_source.h"
#include "perfetto/tracing/track_event_category_registry.h"
// Defines data structures for backing a category registry.
//
// Each category has one enabled/disabled bit per possible data source instance.
// The bits are packed, i.e., each byte holds the state for instances. To
// improve cache locality, the bits for each instance are stored separately from
// the names of the categories:
//
// byte 0 byte 1
// (inst0, inst1, ..., inst7), (inst0, inst1, ..., inst7)
//
#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(...) \
namespace internal { \
constexpr ::perfetto::internal::TrackEventCategory kCategories[] = { \
__VA_ARGS__}; \
constexpr size_t kCategoryCount = \
sizeof(kCategories) / sizeof(kCategories[0]); \
/* The per-instance enable/disable state per category */ \
extern std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
/* The category registry which mediates access to the above structures. */ \
/* The registry is used for two purposes: */ \
/**/ \
/* 1) For looking up categories at build (constexpr) time. */ \
/* 2) For declaring the per-namespace TrackEvent data source. */ \
/**/ \
/* Because usage #1 requires a constexpr type and usage #2 requires an */ \
/* extern type (to avoid declaring a type based on a translation-unit */ \
/* variable), we need two separate copies of the registry with different */ \
/* storage specifiers. */ \
/**/ \
/* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */ \
constexpr ::perfetto::internal::TrackEventCategoryRegistry \
kConstExprCategoryRegistry(kCategoryCount, \
&kCategories[0], \
&g_category_state_storage[0]); \
extern const ::perfetto::internal::TrackEventCategoryRegistry \
kCategoryRegistry; \
} // namespace internal
// In a .cc file, declares storage for each category's runtime state.
#define PERFETTO_INTERNAL_CATEGORY_STORAGE() \
namespace internal { \
std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
constexpr ::perfetto::internal::TrackEventCategoryRegistry \
kCategoryRegistry(kCategoryCount, \
&kCategories[0], \
&g_category_state_storage[0]); \
} // namespace internal
// Defines the TrackEvent data source for the current track event namespace.
#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE() \
struct TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
TrackEvent, &internal::kCategoryRegistry> {}
// At compile time, turns a category name represented by a static string into an
// index into the current category registry. A build error will be generated if
// the category hasn't been registered. See PERFETTO_DEFINE_CATEGORIES.
#define PERFETTO_GET_CATEGORY_INDEX(category) \
::perfetto::internal::TrackEventCategoryRegistry::Validate< \
::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry \
.Find(category)>()
// Efficiently determines whether tracing is enabled for the given category, and
// if so, emits one trace event with the given arguments.
#define PERFETTO_INTERNAL_TRACK_EVENT(category, ...) \
::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::CallIfCategoryEnabled< \
PERFETTO_GET_CATEGORY_INDEX(category)>([&](uint32_t instances) { \
::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceForCategory< \
PERFETTO_GET_CATEGORY_INDEX(category)>(instances, ##__VA_ARGS__); \
})
#endif // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_