1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef SLICE_FILTER_H 17 #define SLICE_FILTER_H 18 19 #include <cstdint> 20 #include <vector> 21 #include "args_set.h" 22 #include "filter_base.h" 23 #include "trace_data_cache.h" 24 #include "trace_streamer_filters.h" 25 #include "triple_map.h" 26 #include "ts_common.h" 27 28 namespace SysTuning { 29 namespace TraceStreamer { 30 struct SliceData { 31 uint64_t timeStamp; 32 int32_t duration; 33 InternalTid internalTid; 34 DataIndex cat; 35 DataIndex name; 36 uint32_t depth; 37 uint64_t index; 38 uint32_t argSetId; 39 }; 40 struct AsyncEvent { 41 uint64_t timeStamp; 42 size_t row; 43 }; 44 class SliceFilter : private FilterBase { 45 public: 46 SliceFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter); 47 ~SliceFilter() override; 48 49 size_t BeginSlice(const std::string& comm, 50 uint64_t timeStamp, 51 uint32_t pid, 52 uint32_t threadGroupId, 53 DataIndex cat, 54 DataIndex nameIndex); 55 size_t BeginBinder(uint64_t timeStamp, uint32_t pid, DataIndex cat, DataIndex nameIndex, ArgsSet args = ArgsSet()); 56 size_t StartSlice(uint64_t timeStamp, 57 uint32_t pid, 58 DataIndex cat, 59 DataIndex nameIndex, 60 ArgsSet& args, 61 SliceData sliceData = SliceData()); 62 size_t AsyncBinder(uint64_t timeStamp, uint32_t pid, DataIndex cat, DataIndex nameIndex, ArgsSet& args); 63 size_t EndBinder(uint64_t timeStamp, 64 uint32_t pid, 65 DataIndex category = INVALID_UINT64, 66 DataIndex name = INVALID_UINT64, 67 ArgsSet args = {}); 68 size_t CompleteSlice(uint64_t timeStamp, 69 uint32_t pid, 70 uint32_t threadGroupId, 71 DataIndex category = INVALID_UINT64, 72 DataIndex name = INVALID_UINT64, 73 ArgsSet args = {}); 74 size_t EndSlice(uint64_t timeStamp, 75 uint32_t pid, 76 uint32_t threadGroupId, 77 DataIndex category = INVALID_UINT64, 78 DataIndex name = INVALID_UINT64); 79 uint64_t 80 StartAsyncSlice(uint64_t timeStamp, uint32_t pid, uint32_t threadGroupId, uint64_t cookie, DataIndex nameIndex); 81 uint64_t FinishAsyncSlice(uint64_t timeStamp, 82 uint32_t pid, 83 uint32_t threadGroupId, 84 uint64_t cookie, 85 DataIndex nameIndex); 86 void IrqHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 87 std::tuple<uint64_t, uint32_t> AddArgs(uint32_t tid, DataIndex key1, DataIndex key2, ArgsSet& args); 88 void IrqHandlerExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args); 89 void IpiHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 90 void IpiHandlerExit(uint64_t timeStamp, uint32_t cpu); 91 void SoftIrqEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 92 void SoftIrqExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args); 93 void Clear(); 94 95 private: 96 struct StackInfo { 97 bool isAsyncEvent = false; 98 uint32_t asyncEventCount = 0; 99 uint32_t asyncEventLastBeginTs = 0; 100 std::vector<SliceData> sliceStack; 101 }; 102 using SlicesStack = std::vector<SliceData>; 103 using StackOfSlices = StackInfo; 104 using StackOnDepth = std::map<uint32_t, bool>; 105 void RememberSliceData(InternalTid internalTid, 106 std::unordered_map<InternalTid, StackOfSlices>& stackMap, 107 SliceData& slice, 108 uint32_t depth, 109 uint64_t index); 110 uint8_t UpdateDepth(bool increase, InternalTid internalTid, int32_t depth = -1); 111 void CloseUnMatchedSlice(int64_t ts, SlicesStack& stack, InternalTid itid); 112 int32_t MatchingIncompleteSliceIndex(const SlicesStack& stack, DataIndex category, DataIndex name); 113 uint8_t CurrentDepth(InternalTid internalTid); 114 void HandleAsyncEventAndOther(ArgsSet args, CallStack* slices, uint64_t lastRow, StackOfSlices& stackInfo); 115 116 private: 117 // The parameter list is tid, cookid, functionName, asyncCallId. 118 TripleMap<uint32_t, uint64_t, DataIndex, uint64_t> asyncEventMap_; 119 // this is only used to calc the layer of the async event in same time range 120 std::map<uint32_t, int8_t> asyncNoEndingEventMap_ = {}; 121 // irq map, key1 is cpu, key2 122 struct IrqRecords { 123 uint64_t ts; 124 size_t row; 125 }; 126 std::unordered_map<uint32_t, IrqRecords> irqEventMap_ = {}; 127 std::unordered_map<uint32_t, IrqRecords> ipiEventMap_ = {}; 128 // irq map, key1 is cpu, key2 129 std::unordered_map<uint32_t, IrqRecords> softIrqEventMap_ = {}; 130 std::map<uint64_t, AsyncEvent> asyncEventFilterMap_ = {}; 131 std::unordered_map<InternalTid, StackOfSlices> sliceStackMap_ = {}; 132 std::unordered_map<InternalTid, StackOfSlices>& binderStackMap_ = sliceStackMap_; 133 std::unordered_map<InternalTid, StackOnDepth> depthHolder_ = {}; 134 std::unordered_map<uint32_t, uint32_t> pidTothreadGroupId_ = {}; 135 uint64_t asyncEventSize_ = 0; 136 uint64_t asyncEventDisMatchCount_ = 0; 137 uint64_t callEventDisMatchCount_ = 0; 138 std::unordered_map<uint32_t, uint32_t> sliceRowToArgsSetId_ = {}; 139 std::unordered_map<uint32_t, uint32_t> argsSetIdToSliceRow_ = {}; 140 std::unordered_map<uint32_t, uint32_t> tidToArgsSetId_ = {}; 141 struct SliceInfo { 142 uint32_t row; 143 ArgsSet args_tracker; 144 }; 145 std::unordered_map<FilterId, std::vector<SliceInfo>> argsSet_ = {}; 146 DataIndex asyncBeginCountId_ = traceDataCache_->GetDataIndex("legacy_unnestable_begin_count"); 147 DataIndex asyncBeginTsId_ = traceDataCache_->GetDataIndex("legacy_unnestable_last_begin_ts"); 148 DataIndex ipiId_ = traceDataCache_->GetDataIndex("IPI"); 149 std::map<uint32_t, uint32_t> irqDataLinker_ = {}; 150 }; 151 } // namespace TraceStreamer 152 } // namespace SysTuning 153 154 #endif // SLICE_FILTER_H 155