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