1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 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 DataIndex cat, 58 DataIndex nameIndex, 59 ArgsSet &args, 60 SliceData sliceData = SliceData()); 61 size_t AsyncBinder(uint64_t timeStamp, uint32_t pid, DataIndex cat, DataIndex nameIndex, ArgsSet &args); 62 size_t EndBinder(uint64_t timeStamp, 63 uint32_t pid, 64 DataIndex category = INVALID_UINT64, 65 DataIndex name = INVALID_UINT64, 66 ArgsSet args = {}); 67 size_t CompleteSlice(uint64_t timeStamp, 68 uint32_t InternalTid, 69 DataIndex category = INVALID_UINT64, 70 DataIndex name = INVALID_UINT64, 71 ArgsSet args = {}); 72 size_t EndSlice(uint64_t timeStamp, 73 uint32_t pid, 74 uint32_t threadGroupId, 75 DataIndex category = INVALID_UINT64, 76 DataIndex name = INVALID_UINT64); 77 uint64_t StartAsyncSlice(uint64_t timeStamp, 78 uint32_t pid, 79 uint32_t threadGroupId, 80 int64_t cookie, 81 DataIndex nameIndex); 82 uint64_t FinishAsyncSlice(uint64_t timeStamp, 83 uint32_t pid, 84 uint32_t threadGroupId, 85 int64_t cookie, 86 DataIndex nameIndex); 87 void StartGEvent(uint64_t timeStamp, uint32_t pid, uint32_t threadGroupId, int64_t cookie, DataIndex nameIndex); 88 uint64_t FinishHEvent(uint64_t timeStamp, uint32_t threadGroupId, int64_t cookie, DataIndex nameIndex); 89 void IrqHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 90 std::tuple<uint64_t, uint32_t> AddArgs(uint32_t tid, DataIndex key1, DataIndex key2, ArgsSet &args); 91 void IrqHandlerExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args); 92 void IpiHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 93 void IpiHandlerExit(uint64_t timeStamp, uint32_t cpu); 94 void SoftIrqEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 95 void SoftIrqExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args); 96 void DmaFence(DmaFenceRow &dmaFenceRow); 97 void Clear(); UpdateReadySize()98 void UpdateReadySize() 99 { 100 UpdateIrqReadySize(); 101 } 102 103 private: 104 struct StackInfo { 105 bool isAsyncEvent = false; 106 uint32_t asyncEventCount = 0; 107 uint32_t asyncEventLastBeginTs = 0; 108 std::vector<SliceData> sliceStack; 109 }; 110 using SlicesStack = std::vector<SliceData>; 111 using StackOfSlices = StackInfo; 112 using StackOnDepth = std::map<uint32_t, bool>; 113 void RememberSliceData(InternalTid internalTid, 114 std::unordered_map<InternalTid, StackOfSlices> &stackMap, 115 SliceData &slice, 116 uint32_t depth, 117 uint64_t index); 118 uint8_t UpdateDepth(bool increase, InternalTid internalTid, int32_t depth = -1); 119 void CloseUnMatchedSlice(int64_t ts, SlicesStack &stack, InternalTid itid); 120 int32_t MatchingIncompleteSliceIndex(const SlicesStack &stack, DataIndex category, DataIndex name); 121 uint8_t CurrentDepth(InternalTid internalTid); 122 void HandleAsyncEventAndOther(ArgsSet args, CallStack *slices, uint64_t lastRow, StackOfSlices &stackInfo); 123 bool UpdateIrqReadySize(); 124 125 private: 126 // The parameter list is tid, cookid, functionName, asyncCallId. 127 TripleMap<uint32_t, int64_t, DataIndex, uint64_t> asyncEventMap_; 128 TripleMap<uint32_t, int64_t, DataIndex, std::vector<uint64_t>> gEventMap_; 129 // this is only used to calc the layer of the async event in same time range 130 std::map<uint32_t, int8_t> asyncNoEndingEventMap_ = {}; 131 // irq map, key1 is cpu, key2 132 struct IrqRecords { 133 uint64_t ts; 134 size_t row; 135 }; 136 std::unordered_map<uint32_t /* cpu */, IrqRecords> irqEventMap_ = {}; 137 std::unordered_map<uint32_t /* cpu */, IrqRecords> ipiEventMap_ = {}; 138 // irq map, key1 is cpu, key2 139 std::unordered_map<uint32_t, IrqRecords> softIrqEventMap_ = {}; 140 std::unordered_map<uint64_t, uint64_t> dmaFenceEventMap_ = {}; 141 std::map<uint64_t, AsyncEvent> asyncEventFilterMap_ = {}; 142 std::map<uint64_t, AsyncEvent> gEventFilterMap_ = {}; 143 std::unordered_map<InternalTid, StackOfSlices> sliceStackMap_ = {}; 144 std::unordered_map<InternalTid, StackOfSlices> &binderStackMap_ = sliceStackMap_; 145 std::unordered_map<InternalTid, StackOnDepth> depthHolder_ = {}; 146 std::unordered_map<uint32_t, uint32_t> pidTothreadGroupId_ = {}; 147 uint64_t asyncEventSize_ = 0; 148 uint64_t gEventSize_ = 0; 149 uint64_t asyncEventDisMatchCount_ = 0; 150 uint64_t callEventDisMatchCount_ = 0; 151 std::unordered_map<uint32_t, uint32_t> sliceRowToArgsSetId_ = {}; 152 std::unordered_map<uint32_t, uint32_t> tidToArgsSetId_ = {}; 153 struct SliceInfo { 154 uint32_t row; 155 ArgsSet args_tracker; 156 }; 157 std::unordered_map<FilterId, std::vector<SliceInfo>> argsSet_ = {}; 158 DataIndex asyncBeginCountId_ = traceDataCache_->GetDataIndex("legacy_unnestable_begin_count"); 159 DataIndex asyncBeginTsId_ = traceDataCache_->GetDataIndex("legacy_unnestable_last_begin_ts"); 160 DataIndex ipiId_ = traceDataCache_->GetDataIndex("IPI"); 161 std::map<uint32_t /* cpu */, uint32_t> irqDataLinker_ = {}; 162 const std::regex categoryReg_ = std::regex(R"((.+)\$\$(.+))"); 163 const uint64_t categoryMatchedIdx_ = 1; 164 }; 165 } // namespace TraceStreamer 166 } // namespace SysTuning 167 168 #endif // SLICE_FILTER_H 169