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