| /* |
| * 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_TRACK_EVENT_H_ |
| #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_ |
| |
| #include "perfetto/base/time.h" |
| #include "perfetto/tracing/internal/track_event_data_source.h" |
| #include "perfetto/tracing/internal/track_event_internal.h" |
| #include "perfetto/tracing/internal/track_event_macros.h" |
| #include "perfetto/tracing/track_event_category_registry.h" |
| #include "protos/perfetto/trace/track_event/track_event.pbzero.h" |
| |
| // This file contains a set of macros designed for instrumenting applications |
| // with track event trace points. While the underlying TrackEvent API can also |
| // be used directly, doing so efficiently requires some care (e.g., to avoid |
| // evaluating arguments while tracing is disabled). These types of optimizations |
| // are abstracted away by the macros below. |
| // |
| // ================ |
| // Quickstart guide |
| // ================ |
| // |
| // To add track events to your application, first define your categories in, |
| // e.g., my_tracing.h: |
| // |
| // PERFETTO_DEFINE_CATEGORIES( |
| // PERFETTO_CATEGORY(base), |
| // PERFETTO_CATEGORY(v8), |
| // PERFETTO_CATEGORY(cc)); |
| // |
| // Then in a single .cc file, e.g., my_tracing.cc: |
| // |
| // #include "my_tracing.h" |
| // PERFETTO_TRACK_EVENT_STATIC_STORAGE(); |
| // |
| // Finally, register track events at startup, after which you can record |
| // events with the TRACE_EVENT macros: |
| // |
| // #include "my_tracing.h" |
| // |
| // int main() { |
| // perfetto::TrackEvent::Register(); |
| // TRACK_EVENT_BEGIN("category", "MyEvent"); |
| // TRACK_EVENT_END("category"); |
| // ... |
| // } |
| // |
| // ==================== |
| // Implementation notes |
| // ==================== |
| // |
| // The track event library consists of the following layers and components. The |
| // classes the internal namespace shouldn't be considered part of the public |
| // API. |
| // .--------------------------------. |
| // .----| TRACE_EVENT |----. |
| // write | | - App instrumentation point | | write |
| // event | '--------------------------------' | arguments |
| // V V |
| // .----------------------------------. .-----------------------------. |
| // | TrackEvent | | TrackEventContext | |
| // | - Registry of event categories | | - One track event instance | |
| // '----------------------------------' '-----------------------------' |
| // | | |
| // | | look up |
| // | is | interning ids |
| // V V |
| // .----------------------------------. .-----------------------------. |
| // | internal::TrackEventDataSource | | TrackEventInternedDataIndex | |
| // | - Perfetto data source | | - Corresponds to a field in | |
| // | - Has TrackEventIncrementalState | | in interned_data.proto | |
| // '----------------------------------' '-----------------------------' |
| // | | ^ |
| // | | owns (1:many) | |
| // | write event '-------------------------' |
| // V |
| // .----------------------------------. |
| // | internal::TrackEventInternal | |
| // | - Outlined code to serialize | |
| // | one track event | |
| // '----------------------------------' |
| // |
| |
| // Each compilation unit can be in exactly one track event namespace, |
| // allowing the overall program to use multiple track event data sources and |
| // category lists if necessary. Use this macro to select the namespace for the |
| // current compilation unit. |
| // |
| // If the program uses multiple track event namespaces, category & track event |
| // registration (see quickstart above) needs to happen for both namespaces |
| // separately. |
| #ifndef PERFETTO_TRACK_EVENT_NAMESPACE |
| #define PERFETTO_TRACK_EVENT_NAMESPACE perfetto |
| #endif |
| |
| // A name for a single category. Wrapped in a macro in case we need to introduce |
| // more fields in the future. |
| #define PERFETTO_CATEGORY(name) \ |
| { #name } |
| |
| // Register the set of available categories by passing a list of categories to |
| // this macro: PERFETTO_CATEGORY(cat1), PERFETTO_CATEGORY(cat2), ... |
| #define PERFETTO_DEFINE_CATEGORIES(...) \ |
| namespace PERFETTO_TRACK_EVENT_NAMESPACE { \ |
| /* The list of category names */ \ |
| PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__); \ |
| /* The track event data source for this set of categories */ \ |
| PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(); \ |
| } // namespace PERFETTO_TRACK_EVENT_NAMESPACE |
| |
| // Allocate storage for each category by using this macro once per track event |
| // namespace. |
| #define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \ |
| namespace PERFETTO_TRACK_EVENT_NAMESPACE { \ |
| PERFETTO_INTERNAL_CATEGORY_STORAGE(); \ |
| } // namespace PERFETTO_TRACK_EVENT_NAMESPACE |
| |
| // Begin a thread-scoped slice under |category| with the title |name|. Both |
| // strings must be static constants. The track event is only recorded if |
| // |category| is enabled for a tracing session. |
| #define TRACE_EVENT_BEGIN(category, name, ...) \ |
| PERFETTO_INTERNAL_TRACK_EVENT( \ |
| category, name, \ |
| ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__) |
| |
| // End a thread-scoped slice under |category|. |
| #define TRACE_EVENT_END(category, ...) \ |
| PERFETTO_INTERNAL_TRACK_EVENT( \ |
| category, nullptr, \ |
| ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END, ##__VA_ARGS__) |
| |
| // TODO(skyostil): Add arguments. |
| // TODO(skyostil): Add scoped events. |
| // TODO(skyostil): Add async events. |
| // TODO(skyostil): Add flow events. |
| // TODO(skyostil): Add instant events. |
| // TODO(skyostil): Add counters. |
| |
| #endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_ |