• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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_STATE_TRACKER_H_
18 #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
19 
20 #include "perfetto/base/export.h"
21 
22 #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
23 
24 #include <map>
25 #include <string>
26 #include <vector>
27 
28 namespace perfetto {
29 namespace protos {
30 namespace pbzero {
31 class TracePacket_Decoder;
32 class TrackEvent;
33 class TrackEvent_Decoder;
34 }  // namespace pbzero
35 }  // namespace protos
36 
37 // A helper for keeping track of incremental state when intercepting track
38 // events.
39 class PERFETTO_EXPORT TrackEventStateTracker {
40  public:
41   ~TrackEventStateTracker();
42 
43   struct StackFrame {
44     uint64_t timestamp{};
45 
46     // Only one of |name| and |name_iid| will be set.
47     std::string name;
48     uint64_t name_iid{};
49     uint64_t name_hash{};
50 
51     // Only one of |category| and |category_iid| will be set.
52     std::string category;
53     uint64_t category_iid{};
54   };
55 
56   struct Track {
57     uint64_t uuid{};
58     uint32_t index{};  // Ordinal number for the track in the tracing session.
59 
60     std::string name;
61     int64_t pid{};
62     int64_t tid{};
63 
64     // Opaque user data associated with the track.
65     std::vector<uint8_t> user_data;
66 
67     // Stack of opened slices on this track.
68     std::vector<StackFrame> stack;
69   };
70 
71   // State for a single trace writer sequence (typically a single thread).
72   struct SequenceState {
73     // Trace packet sequence defaults.
74     Track track;
75 
76     // Interned state.
77 #if PERFETTO_DCHECK_IS_ON()
78     uint32_t sequence_id{};
79 #endif
80     std::map<uint64_t /*iid*/, std::string> event_names;
81     std::map<uint64_t /*iid*/, std::string> event_categories;
82     std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
83   };
84 
85   // State for the entire tracing session. Shared by all trace writer sequences
86   // participating in the session.
87   struct SessionState {
88     // Non-thread-bound tracks.
89     std::map<uint64_t /*uuid*/, Track> tracks;
90   };
91 
92   // Represents a single decoded track event (without arguments).
93   struct ParsedTrackEvent {
94     explicit ParsedTrackEvent(
95         const perfetto::protos::pbzero::TrackEvent::Decoder&);
96 
97     // Underlying event.
98     const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;
99 
100     // Event metadata.
101     uint64_t timestamp_ns{};
102     uint64_t duration_ns{};
103 
104     size_t stack_depth{};
105 
106     protozero::ConstChars category{};
107     protozero::ConstChars name{};
108     uint64_t name_hash{};
109   };
110 
111   // Interface used by the tracker to access tracing session and sequence state
112   // and to report parsed track events.
113   class Delegate {
114    public:
115     virtual ~Delegate();
116 
117     // Called to retrieve the session-global state shared by all sequences. The
118     // returned pointer must remain valid (locked) throughout the call to
119     // |ProcessTracePacket|.
120     virtual SessionState* GetSessionState() = 0;
121 
122     // Called when the metadata (e.g., name) for a track changes. |Track| can be
123     // modified by the callback to attach user data.
124     virtual void OnTrackUpdated(Track&) = 0;
125 
126     // If the packet given to |ProcessTracePacket| contains a track event, this
127     // method is called to report the properties of that event. Note that memory
128     // pointers in |TrackEvent| will only be valid during this call.
129     virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
130   };
131 
132   // Process a single trace packet, reporting any contained track event back via
133   // the delegate interface. |SequenceState| must correspond to the sequence
134   // that was used to write the packet.
135   static void ProcessTracePacket(Delegate&,
136                                  SequenceState&,
137                                  const protos::pbzero::TracePacket_Decoder&);
138 
139  private:
140   static void UpdateIncrementalState(
141       Delegate&,
142       SequenceState&,
143       const protos::pbzero::TracePacket_Decoder&);
144 };
145 
146 }  // namespace perfetto
147 
148 #endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
149