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 DataIndex category = INVALID_UINT64, 71 DataIndex name = INVALID_UINT64, 72 ArgsSet args = {}); 73 size_t EndSlice(uint64_t timestamp, 74 uint32_t pid, 75 uint32_t threadGroupId, 76 DataIndex category = INVALID_UINT64, 77 DataIndex name = INVALID_UINT64); 78 void StartAsyncSlice(uint64_t timestamp, uint32_t pid, 79 uint32_t threadGroupId, uint64_t cookie, DataIndex nameIndex); 80 void 81 FinishAsyncSlice(uint64_t timestamp, uint32_t pid, 82 uint32_t threadGroupId, uint64_t cookie, DataIndex nameIndex); 83 void IrqHandlerEntry(uint64_t timestamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 84 std::tuple<uint64_t, uint32_t> AddArgs(uint32_t tid, DataIndex key1, DataIndex key2, ArgsSet& args); 85 void IrqHandlerExit(uint64_t timestamp, uint32_t cpu, ArgsSet args); 86 void SoftIrqEntry(uint64_t timestamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex); 87 void SoftIrqExit(uint64_t timestamp, uint32_t cpu, ArgsSet args); 88 void Clear(); 89 90 private: 91 struct StackInfo { 92 bool isAsyncEvent = false; 93 uint32_t asyncEventCount = 0; 94 uint32_t asyncEventLastBeginTs = 0; 95 std::vector<SliceData> sliceStack; 96 }; 97 using SlicesStack = std::vector<SliceData>; 98 using StackOfSlices = StackInfo; 99 using StackOnDepth = std::map<uint32_t, bool>; 100 void RememberSliceData(InternalTid internalTid, 101 std::unordered_map<InternalTid, StackOfSlices>& stackMap, 102 SliceData& slice, 103 uint32_t depth, 104 uint64_t index); 105 uint8_t UpdateDepth(bool increase, InternalTid internalTid, int32_t depth = -1); 106 void CloseUnMatchedSlice(int64_t ts, SlicesStack& stack, InternalTid itid); 107 int32_t MatchingIncompleteSliceIndex(const SlicesStack& stack, DataIndex category, DataIndex name); 108 uint8_t CurrentDepth(InternalTid internalTid); 109 110 private: 111 // The parameter list is tid, cookid, functionName, asyncCallId. 112 TripleMap<uint32_t, uint64_t, DataIndex, uint64_t> asyncEventMap_; 113 // this is only used to calc the layer of the async event in same time range 114 std::map<uint32_t, int8_t> asyncNoEndingEventMap_ = {}; 115 // irq map, key1 is cpu, key2 116 struct IrqRecords { 117 uint64_t ts; 118 size_t row; 119 }; 120 std::unordered_map<uint32_t, IrqRecords> irqEventMap_ = {}; 121 // irq map, key1 is cpu, key2 122 std::unordered_map<uint32_t, IrqRecords> softIrqEventMap_ = {}; 123 std::map<uint64_t, AsyncEvent> asyncEventFilterMap_ = {}; 124 std::unordered_map<InternalTid, StackOfSlices> sliceStackMap_ = {}; 125 std::unordered_map<InternalTid, StackOfSlices>& binderStackMap_ = sliceStackMap_; 126 std::unordered_map<InternalTid, StackOnDepth> depthHolder_ = {}; 127 std::unordered_map<uint32_t, uint32_t> pidTothreadGroupId_ = {}; 128 uint64_t asyncEventSize_ = 0; 129 uint64_t asyncEventDisMatchCount = 0; 130 uint64_t callEventDisMatchCount = 0; 131 std::unordered_map<uint32_t, uint32_t> sliceRowToArgsSetId_ = {}; 132 std::unordered_map<uint32_t, uint32_t> argsSetIdToSliceRow_ = {}; 133 std::unordered_map<uint32_t, uint32_t> tidToArgsSetId_ = {}; 134 struct SliceInfo { 135 uint32_t row; 136 ArgsSet args_tracker; 137 }; 138 std::unordered_map<FilterId, std::vector<SliceInfo>> argsSet_ = {}; 139 DataIndex asyncBeginCountId_ = traceDataCache_->GetDataIndex("legacy_unnestable_begin_count"); 140 DataIndex asyncBeginTsId_ = traceDataCache_->GetDataIndex("legacy_unnestable_last_begin_ts"); 141 }; 142 } // namespace TraceStreamer 143 } // namespace SysTuning 144 145 #endif // SLICE_FILTER_H 146