| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_ |
| #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_ |
| |
| #include "perfetto/base/export.h" |
| |
| #include "protos/perfetto/trace/track_event/track_event.pbzero.h" |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| namespace perfetto { |
| namespace protos { |
| namespace pbzero { |
| class TracePacket_Decoder; |
| class TrackEvent; |
| class TrackEvent_Decoder; |
| } // namespace pbzero |
| } // namespace protos |
| |
| // A helper for keeping track of incremental state when intercepting track |
| // events. |
| class PERFETTO_EXPORT TrackEventStateTracker { |
| public: |
| ~TrackEventStateTracker(); |
| |
| struct StackFrame { |
| uint64_t timestamp{}; |
| |
| // Only one of |name| and |name_iid| will be set. |
| std::string name; |
| uint64_t name_iid{}; |
| uint64_t name_hash{}; |
| |
| // Only one of |category| and |category_iid| will be set. |
| std::string category; |
| uint64_t category_iid{}; |
| }; |
| |
| struct Track { |
| uint64_t uuid{}; |
| uint32_t index{}; // Ordinal number for the track in the tracing session. |
| |
| std::string name; |
| int64_t pid{}; |
| int64_t tid{}; |
| |
| // Opaque user data associated with the track. |
| std::vector<uint8_t> user_data; |
| |
| // Stack of opened slices on this track. |
| std::vector<StackFrame> stack; |
| }; |
| |
| // State for a single trace writer sequence (typically a single thread). |
| struct SequenceState { |
| // Trace packet sequence defaults. |
| Track track; |
| |
| // Interned state. |
| #if PERFETTO_DCHECK_IS_ON() |
| uint32_t sequence_id{}; |
| #endif |
| std::map<uint64_t /*iid*/, std::string> event_names; |
| std::map<uint64_t /*iid*/, std::string> event_categories; |
| std::map<uint64_t /*iid*/, std::string> debug_annotation_names; |
| // Current absolute timestamp of the incremental clock. |
| uint64_t most_recent_absolute_time_ns = 0; |
| // default_clock_id == 0 means, no default clock_id is set. |
| uint32_t default_clock_id = 0; |
| }; |
| |
| // State for the entire tracing session. Shared by all trace writer sequences |
| // participating in the session. |
| struct SessionState { |
| // Non-thread-bound tracks. |
| std::map<uint64_t /*uuid*/, Track> tracks; |
| }; |
| |
| // Represents a single decoded track event (without arguments). |
| struct ParsedTrackEvent { |
| explicit ParsedTrackEvent( |
| const perfetto::protos::pbzero::TrackEvent::Decoder&); |
| |
| // Underlying event. |
| const perfetto::protos::pbzero::TrackEvent::Decoder& track_event; |
| |
| // Event metadata. |
| uint64_t timestamp_ns{}; |
| uint64_t duration_ns{}; |
| |
| size_t stack_depth{}; |
| |
| protozero::ConstChars category{}; |
| protozero::ConstChars name{}; |
| uint64_t name_hash{}; |
| }; |
| |
| // Interface used by the tracker to access tracing session and sequence state |
| // and to report parsed track events. |
| class Delegate { |
| public: |
| virtual ~Delegate(); |
| |
| // Called to retrieve the session-global state shared by all sequences. The |
| // returned pointer must remain valid (locked) throughout the call to |
| // |ProcessTracePacket|. |
| virtual SessionState* GetSessionState() = 0; |
| |
| // Called when the metadata (e.g., name) for a track changes. |Track| can be |
| // modified by the callback to attach user data. |
| virtual void OnTrackUpdated(Track&) = 0; |
| |
| // If the packet given to |ProcessTracePacket| contains a track event, this |
| // method is called to report the properties of that event. Note that memory |
| // pointers in |TrackEvent| will only be valid during this call. |
| virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0; |
| }; |
| |
| // Process a single trace packet, reporting any contained track event back via |
| // the delegate interface. |SequenceState| must correspond to the sequence |
| // that was used to write the packet. |
| static void ProcessTracePacket(Delegate&, |
| SequenceState&, |
| const protos::pbzero::TracePacket_Decoder&); |
| |
| private: |
| static void UpdateIncrementalState( |
| Delegate&, |
| SequenceState&, |
| const protos::pbzero::TracePacket_Decoder&); |
| }; |
| |
| } // namespace perfetto |
| |
| #endif // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_ |