• 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_COMPONENT 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     // Current absolute timestamp of the incremental clock.
84     uint64_t most_recent_absolute_time_ns = 0;
85     // default_clock_id == 0 means, no default clock_id is set.
86     uint32_t default_clock_id = 0;
87   };
88 
89   // State for the entire tracing session. Shared by all trace writer sequences
90   // participating in the session.
91   struct SessionState {
92     // Non-thread-bound tracks.
93     std::map<uint64_t /*uuid*/, Track> tracks;
94   };
95 
96   // Represents a single decoded track event (without arguments).
97   struct ParsedTrackEvent {
98     explicit ParsedTrackEvent(
99         const perfetto::protos::pbzero::TrackEvent::Decoder&);
100 
101     // Underlying event.
102     const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;
103 
104     // Event metadata.
105     uint64_t timestamp_ns{};
106     uint64_t duration_ns{};
107 
108     size_t stack_depth{};
109 
110     protozero::ConstChars category{};
111     protozero::ConstChars name{};
112     uint64_t name_hash{};
113   };
114 
115   // Interface used by the tracker to access tracing session and sequence state
116   // and to report parsed track events.
117   class Delegate {
118    public:
119     virtual ~Delegate();
120 
121     // Called to retrieve the session-global state shared by all sequences. The
122     // returned pointer must remain valid (locked) throughout the call to
123     // |ProcessTracePacket|.
124     virtual SessionState* GetSessionState() = 0;
125 
126     // Called when the metadata (e.g., name) for a track changes. |Track| can be
127     // modified by the callback to attach user data.
128     virtual void OnTrackUpdated(Track&) = 0;
129 
130     // If the packet given to |ProcessTracePacket| contains a track event, this
131     // method is called to report the properties of that event. Note that memory
132     // pointers in |TrackEvent| will only be valid during this call.
133     virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
134   };
135 
136   // Process a single trace packet, reporting any contained track event back via
137   // the delegate interface. |SequenceState| must correspond to the sequence
138   // that was used to write the packet.
139   static void ProcessTracePacket(Delegate&,
140                                  SequenceState&,
141                                  const protos::pbzero::TracePacket_Decoder&);
142 
143  private:
144   static void UpdateIncrementalState(
145       Delegate&,
146       SequenceState&,
147       const protos::pbzero::TracePacket_Decoder&);
148 };
149 
150 }  // namespace perfetto
151 
152 #endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
153