| /* |
| * 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. |
| */ |
| |
| #ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_ |
| #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_ |
| |
| #include "perfetto/tracing/event_context.h" |
| #include "perfetto/tracing/track.h" |
| |
| #include <functional> |
| |
| namespace perfetto { |
| |
| // A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT |
| // inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42)); |
| class Flow { |
| public: |
| // |flow_id| which is local within a given process (e.g. atomic counter xor'ed |
| // with feature-specific value). This value is xor'ed with Perfetto's internal |
| // process track id to attempt to ensure that it's globally-unique. |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| ProcessScoped(uint64_t flow_id) { |
| return Global(flow_id ^ Track::process_uuid); |
| } |
| |
| // Same as above, but construct an id from a pointer. |
| // NOTE: After the object is destroyed, the value of |ptr| can be reused for a |
| // different object (in particular if the object is allocated on a stack). |
| // Please ensure that you emit a trace event with the flow id of |
| // perfetto::TerminatingFlow::FromPointer(this) from the destructor of the |
| // object to avoid accidental conflicts. |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| FromPointer(void* ptr) { |
| return ProcessScoped(reinterpret_cast<uintptr_t>(ptr)); |
| } |
| |
| // Add the |flow_id|. The caller is responsible for ensuring that it's |
| // globally-unique (e.g. by generating a random value). This should be used |
| // only for flow events which cross the process boundary (e.g. IPCs). |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| Global(uint64_t flow_id) { |
| return [flow_id](perfetto::EventContext& ctx) { |
| ctx.event()->add_flow_ids(flow_id); |
| }; |
| } |
| |
| // TODO(altimin): Remove once converting a single usage in Chromium. |
| explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {} |
| |
| void operator()(EventContext& ctx) { ctx.event()->add_flow_ids(flow_id_); } |
| |
| private: |
| uint64_t flow_id_; |
| }; |
| |
| // A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT |
| // inline. |
| class TerminatingFlow { |
| public: |
| // See `Flow::ProcessScoped(uint64_t)`. |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| ProcessScoped(uint64_t flow_id) { |
| return Global(flow_id ^ Track::process_uuid); |
| } |
| |
| // See `Flow::FromPointer(void*)`. |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| FromPointer(void* ptr) { |
| return ProcessScoped(reinterpret_cast<uintptr_t>(ptr)); |
| } |
| |
| // See `Flow::Global(uint64_t)`. |
| static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)> |
| Global(uint64_t flow_id) { |
| return [flow_id](perfetto::EventContext& ctx) { |
| ctx.event()->add_terminating_flow_ids(flow_id); |
| }; |
| } |
| }; |
| |
| } // namespace perfetto |
| |
| #endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_ |