• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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