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