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 SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_ 19 20 #include <stdint.h> 21 22 #include "perfetto/ext/base/flat_hash_map.h" 23 #include "src/trace_processor/importers/common/args_tracker.h" 24 #include "src/trace_processor/storage/trace_storage.h" 25 #include "src/trace_processor/types/trace_processor_context.h" 26 27 namespace perfetto { 28 namespace trace_processor { 29 30 using FlowId = uint64_t; 31 32 class FlowTracker { 33 public: 34 explicit FlowTracker(TraceProcessorContext*); 35 ~FlowTracker(); 36 37 void InsertFlow(SliceId slice_out_id, SliceId slice_in_id); 38 39 // These methods track flow ids associated with slices and create flows as 40 // needed. 41 // If you don't have flow ids associated with slices, you should use the 42 // InsertFlow method above. 43 void Begin(SliceId slice_id, FlowId flow_id); 44 void Step(SliceId slice_id, FlowId flow_id); 45 void End(SliceId track_id, FlowId flow_id, bool close_flow); 46 47 // These methods assume you have created a FlowId via GetFlowIdForV1Event and 48 // tie the flow id to the currently open slice on a given track. If you don't 49 // have a v1 event you should use the methods above. 50 void Begin(TrackId track_id, FlowId flow_id); 51 void Step(TrackId track_id, FlowId flow_id); 52 53 // When |bind_enclosing_slice| is true we will connect the flow to the 54 // currently open slice on the track, when false we will connect the flow to 55 // the next slice to be opened on the track. 56 // When |close_flow| is true it will mark this as the singular end of the 57 // flow, however if there are multiple end points this should be set to 58 // false. Both parameters are only needed for v1 flow events support 59 void End(TrackId track_id, 60 FlowId flow_id, 61 bool bind_enclosing_slice, 62 bool close_flow); 63 64 bool IsActive(FlowId flow_id) const; 65 66 FlowId GetFlowIdForV1Event(uint64_t source_id, StringId cat, StringId name); 67 68 void ClosePendingEventsOnTrack(TrackId track_id, SliceId slice_id); 69 70 private: 71 struct V1FlowId { 72 uint64_t source_id; 73 StringId cat; 74 StringId name; 75 76 bool operator==(const V1FlowId& o) const { 77 return o.source_id == source_id && o.cat == cat && o.name == name; 78 } 79 }; 80 81 struct V1FlowIdHasher { operatorV1FlowIdHasher82 size_t operator()(const V1FlowId& c) const { 83 return std::hash<uint64_t>{}( 84 base::Hasher::Combine(c.source_id, c.cat.raw_id(), c.name.raw_id())); 85 } 86 }; 87 88 using FlowToSourceSliceMap = base::FlatHashMap<FlowId, SliceId>; 89 using PendingFlowsMap = base::FlatHashMap<TrackId, std::vector<FlowId>>; 90 using V1FlowIdToFlowIdMap = 91 base::FlatHashMap<V1FlowId, FlowId, V1FlowIdHasher>; 92 using FlowIdToV1FlowId = base::FlatHashMap<FlowId, V1FlowId>; 93 94 void InsertFlow(FlowId flow_id, 95 SliceId outgoing_slice_id, 96 SliceId incoming_slice_id); 97 98 // List of flow end calls waiting for the next slice 99 PendingFlowsMap pending_flow_ids_map_; 100 101 // Flows generated by Begin() or Step() 102 FlowToSourceSliceMap flow_to_slice_map_; 103 104 V1FlowIdToFlowIdMap v1_flow_id_to_flow_id_map_; 105 FlowIdToV1FlowId flow_id_to_v1_flow_id_map_; 106 uint32_t v1_id_counter_ = 0; 107 108 TraceProcessorContext* const context_; 109 110 StringId name_key_id_; 111 StringId cat_key_id_; 112 }; 113 114 } // namespace trace_processor 115 } // namespace perfetto 116 117 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_ 118