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