• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
18 #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
19 
20 #include "perfetto/tracing/event_context.h"
21 #include "perfetto/tracing/track.h"
22 
23 #include <functional>
24 
25 namespace perfetto {
26 
27 // A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT
28 // inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42));
29 class Flow {
30  public:
31   // |flow_id| which is local within a given process (e.g. atomic counter xor'ed
32   // with feature-specific value). This value is xor'ed with Perfetto's internal
33   // process track id to attempt to ensure that it's globally-unique.
34   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
ProcessScoped(uint64_t flow_id)35   ProcessScoped(uint64_t flow_id) {
36     return Global(flow_id ^ Track::process_uuid);
37   }
38 
39   // Same as above, but construct an id from a pointer.
40   // NOTE: After the object is destroyed, the value of |ptr| can be reused for a
41   // different object (in particular if the object is allocated on a stack).
42   // Please ensure that you emit a trace event with the flow id of
43   // perfetto::TerminatingFlow::FromPointer(this) from the destructor of the
44   // object to avoid accidental conflicts.
45   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
FromPointer(void * ptr)46   FromPointer(void* ptr) {
47     return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
48   }
49 
50   // Add the |flow_id|. The caller is responsible for ensuring that it's
51   // globally-unique (e.g. by generating a random value). This should be used
52   // only for flow events which cross the process boundary (e.g. IPCs).
53   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
Global(uint64_t flow_id)54   Global(uint64_t flow_id) {
55     return [flow_id](perfetto::EventContext& ctx) {
56       ctx.event()->add_flow_ids(flow_id);
57     };
58   }
59 
60   // TODO(altimin): Remove once converting a single usage in Chromium.
Flow(uint64_t flow_id)61   explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {}
62 
operator()63   void operator()(EventContext& ctx) { ctx.event()->add_flow_ids(flow_id_); }
64 
65  private:
66   uint64_t flow_id_;
67 };
68 
69 // A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT
70 // inline.
71 class TerminatingFlow {
72  public:
73   // See `Flow::ProcessScoped(uint64_t)`.
74   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
ProcessScoped(uint64_t flow_id)75   ProcessScoped(uint64_t flow_id) {
76     return Global(flow_id ^ Track::process_uuid);
77   }
78 
79   // See `Flow::FromPointer(void*)`.
80   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
FromPointer(void * ptr)81   FromPointer(void* ptr) {
82     return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
83   }
84 
85   // See `Flow::Global(uint64_t)`.
86   static PERFETTO_ALWAYS_INLINE inline std::function<void(EventContext&)>
Global(uint64_t flow_id)87   Global(uint64_t flow_id) {
88     return [flow_id](perfetto::EventContext& ctx) {
89       ctx.event()->add_terminating_flow_ids(flow_id);
90     };
91   }
92 };
93 
94 }  // namespace perfetto
95 
96 #endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
97