• 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 #include "slice_filter.h"
17 #include <cstdint>
18 #include <limits>
19 #include <optional>
20 
21 #include "args_filter.h"
22 #include "log.h"
23 #include "measure_filter.h"
24 #include "process_filter.h"
25 #include "stat_filter.h"
26 #include "string_to_numerical.h"
27 #include "ts_common.h"
28 
29 namespace SysTuning {
30 namespace TraceStreamer {
31 using namespace SysTuning::base;
SliceFilter(TraceDataCache * dataCache,const TraceStreamerFilters * filter)32 SliceFilter::SliceFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter)
33     : FilterBase(dataCache, filter), asyncEventMap_(INVALID_UINT64)
34 {
35 }
36 
37 SliceFilter::~SliceFilter() = default;
38 
BeginSlice(const std::string & comm,uint64_t timeStamp,uint32_t pid,uint32_t threadGroupId,DataIndex cat,DataIndex nameIndex)39 size_t SliceFilter::BeginSlice(const std::string& comm,
40                                uint64_t timeStamp,
41                                uint32_t pid,
42                                uint32_t threadGroupId,
43                                DataIndex cat,
44                                DataIndex nameIndex)
45 {
46     InternalTid internalTid = INVALID_ITID;
47     if (threadGroupId > 0) {
48         internalTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithPidAndName(pid, threadGroupId, comm);
49         pidTothreadGroupId_[pid] = threadGroupId;
50     } else {
51         internalTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(timeStamp, pid, comm);
52     }
53     // make a SliceData DataItem, {timeStamp, dur, internalTid, cat, nameIndex}
54     SliceData sliceData = {timeStamp, -1, internalTid, cat, nameIndex};
55     ArgsSet args;
56     return StartSlice(timeStamp, pid, cat, nameIndex, args, sliceData);
57 }
58 
IrqHandlerEntry(uint64_t timeStamp,uint32_t cpu,DataIndex catalog,DataIndex nameIndex)59 void SliceFilter::IrqHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex)
60 {
61     // clear ipi for current cpu and nameIndex
62     irqDataLinker_.erase(cpu);
63     SliceData sliceData = {timeStamp, 0, cpu, catalog, nameIndex};
64     auto slices = traceDataCache_->GetIrqData();
65     size_t index = slices->AppendInternalSlice(
66         sliceData.timeStamp, sliceData.duration, sliceData.internalTid, sliceData.cat,
67         GetNameASCIISumNoNum(traceDataCache_->GetDataFromDict(sliceData.name)), sliceData.name, 0, std::nullopt);
68     if (irqEventMap_.count(cpu)) {
69         // not match
70         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_DATA_LOST);
71         irqEventMap_.at(cpu) = {timeStamp, index};
72     } else {
73         irqEventMap_[cpu] = {timeStamp, index};
74     }
75     return;
76 }
77 
IrqHandlerExit(uint64_t timeStamp,uint32_t cpu,ArgsSet args)78 void SliceFilter::IrqHandlerExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args)
79 {
80     if (!irqEventMap_.count(cpu)) {
81         // not match
82         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_NOTMATCH);
83         return;
84     }
85     uint32_t argSetId = INVALID_UINT32;
86     auto slices = traceDataCache_->GetIrqData();
87     argSetId = streamFilters_->argsFilter_->NewArgs(args);
88     slices->SetIrqDurAndArg(irqEventMap_.at(cpu).row, timeStamp, argSetId);
89     auto internalEventRow = irqDataLinker_.find(cpu);
90     if (internalEventRow != irqDataLinker_.end()) {
91         slices->SetArgSetId(internalEventRow->second, slices->ArgSetIdsData()[irqEventMap_.at(cpu).row]);
92         slices->SetDurationEx(irqEventMap_.at(cpu).row, slices->DursData()[internalEventRow->second]);
93     } else {
94         slices->SetFlag(irqEventMap_.at(cpu).row, 1);
95     }
96     irqDataLinker_.erase(cpu);
97     irqEventMap_.erase(cpu);
98     return;
99 }
100 
IpiHandlerEntry(uint64_t timeStamp,uint32_t cpu,DataIndex catalog,DataIndex nameIndex)101 void SliceFilter::IpiHandlerEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex)
102 {
103     irqDataLinker_.erase(cpu);
104     SliceData sliceData = {timeStamp, 0, cpu, catalog, nameIndex};
105     auto slices = traceDataCache_->GetIrqData();
106     size_t index = slices->AppendInternalSlice(
107         sliceData.timeStamp, sliceData.duration, sliceData.internalTid, sliceData.cat,
108         GetNameASCIISumNoNum(traceDataCache_->GetDataFromDict(sliceData.name)), sliceData.name, 0, std::nullopt);
109     if (ipiEventMap_.count(cpu)) {
110         // not match
111         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_DATA_LOST);
112         ipiEventMap_.at(cpu) = {timeStamp, index};
113     } else {
114         ipiEventMap_[cpu] = {timeStamp, index};
115     }
116     return;
117 }
IpiHandlerExit(uint64_t timeStamp,uint32_t cpu)118 void SliceFilter::IpiHandlerExit(uint64_t timeStamp, uint32_t cpu)
119 {
120     if (!ipiEventMap_.count(cpu)) {
121         // not match
122         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_DATA_LOST);
123         return;
124     }
125     auto slices = traceDataCache_->GetIrqData();
126     slices->SetDurationWithFlag(ipiEventMap_.at(cpu).row, timeStamp);
127     irqDataLinker_.emplace(cpu, ipiEventMap_.at(cpu).row);
128     ipiEventMap_.erase(cpu);
129 }
SoftIrqEntry(uint64_t timeStamp,uint32_t cpu,DataIndex catalog,DataIndex nameIndex)130 void SliceFilter::SoftIrqEntry(uint64_t timeStamp, uint32_t cpu, DataIndex catalog, DataIndex nameIndex)
131 {
132     SliceData sliceData = {timeStamp, 0, cpu, catalog, nameIndex};
133     auto slices = traceDataCache_->GetIrqData();
134     size_t index = slices->AppendInternalSlice(
135         sliceData.timeStamp, sliceData.duration, sliceData.internalTid, sliceData.cat,
136         GetNameASCIISumNoNum(traceDataCache_->GetDataFromDict(sliceData.name)), sliceData.name, 0, std::nullopt);
137     if (softIrqEventMap_.count(cpu)) {
138         // not match
139         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_DATA_LOST);
140         softIrqEventMap_.at(cpu) = {timeStamp, index};
141     } else {
142         softIrqEventMap_[cpu] = {timeStamp, index};
143     }
144     return;
145 }
146 
SoftIrqExit(uint64_t timeStamp,uint32_t cpu,ArgsSet args)147 void SliceFilter::SoftIrqExit(uint64_t timeStamp, uint32_t cpu, ArgsSet args)
148 {
149     if (!softIrqEventMap_.count(cpu)) {
150         // not match
151         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_DATA_LOST);
152         return;
153     }
154     uint32_t argSetId = INVALID_UINT32;
155     auto slices = traceDataCache_->GetIrqData();
156     argSetId = streamFilters_->argsFilter_->NewArgs(args);
157     slices->SetIrqDurAndArg(softIrqEventMap_.at(cpu).row, timeStamp, argSetId);
158     softIrqEventMap_.erase(cpu);
159     return;
160 }
161 
RememberSliceData(InternalTid internalTid,std::unordered_map<InternalTid,StackOfSlices> & stackMap,SliceData & slice,uint32_t depth,uint64_t index)162 void SliceFilter::RememberSliceData(InternalTid internalTid,
163                                     std::unordered_map<InternalTid, StackOfSlices>& stackMap,
164                                     SliceData& slice,
165                                     uint32_t depth,
166                                     uint64_t index)
167 {
168     if (stackMap.find(internalTid) == stackMap.end()) {
169         auto& sliceStack = stackMap[internalTid].sliceStack; // this can be a empty call, but it does not matter
170         slice.depth = depth;
171         slice.index = index;
172         sliceStack.push_back(slice);
173     } else {
174         auto& sliceStack = stackMap.at(internalTid).sliceStack; // this can be a empty call, but it does not matter
175         slice.depth = depth;
176         slice.index = index;
177         sliceStack.push_back(slice);
178     }
179 }
AsyncBinder(uint64_t timeStamp,uint32_t pid,DataIndex cat,DataIndex nameIndex,ArgsSet & args)180 size_t SliceFilter::AsyncBinder(uint64_t timeStamp, uint32_t pid, DataIndex cat, DataIndex nameIndex, ArgsSet& args)
181 {
182     InternalTid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(timeStamp, pid);
183     SliceData sliceData = {timeStamp, 0, internalTid, cat, nameIndex};
184     return StartSlice(timeStamp, pid, cat, nameIndex, args, std::move(sliceData));
185 }
CurrentDepth(InternalTid internalTid)186 uint8_t SliceFilter::CurrentDepth(InternalTid internalTid)
187 {
188     if (depthHolder_.find(internalTid) == depthHolder_.end()) {
189         return 0;
190     }
191     auto& depthMap = depthHolder_.at(internalTid);
192     auto depthSize = depthMap.size();
193     for (int32_t i = depthSize - 1; i >= 0; i--) {
194         if (depthMap.at(i)) {
195             return i;
196         }
197     }
198     return 0;
199 }
UpdateDepth(bool increase,InternalTid internalTid,int32_t depth)200 uint8_t SliceFilter::UpdateDepth(bool increase, InternalTid internalTid, int32_t depth)
201 {
202     if (increase) {
203         if (depthHolder_.find(internalTid) == depthHolder_.end()) {
204             StackOnDepth tmp;
205             tmp.insert(std::make_pair(0, true));
206             depthHolder_.insert(std::make_pair(internalTid, tmp));
207             return 0;
208         }
209         auto& depthMap = depthHolder_.at(internalTid);
210         auto depthSize = depthMap.size();
211         auto lastIndex = 0;
212         for (int32_t i = depthSize - 1; i >= 0; i--) {
213             if (depthMap.at(i) && (i == depthSize - 1)) {
214                 depthMap.insert(std::make_pair(depthSize, true));
215                 return depthSize;
216             }
217             if (depthMap.at(i)) {
218                 break;
219             }
220             lastIndex = i;
221         }
222 
223         if (!depthMap.at(lastIndex)) {
224             depthMap.at(lastIndex) = true;
225             return lastIndex;
226         }
227     } else {
228         if (depthHolder_.find(internalTid) == depthHolder_.end()) {
229             TS_LOGE("internalTid not found");
230             return 0;
231         }
232         auto& depthMap = depthHolder_.at(internalTid);
233         if (depthMap.find(depth) == depthMap.end()) {
234             return 0;
235         }
236         depthMap.at(depth) = false;
237     }
238     return depth;
239 }
240 
CloseUnMatchedSlice(int64_t ts,SlicesStack & stack,InternalTid itid)241 void SliceFilter::CloseUnMatchedSlice(int64_t ts, SlicesStack& stack, InternalTid itid)
242 {
243     auto slices = traceDataCache_->GetInternalSlicesData();
244     bool incomplete = false;
245     for (int32_t i = stack.size() - 1; i >= 0; i--) {
246         uint32_t sliceIdx = stack[i].index;
247         int64_t startTs = slices->TimeStampData()[sliceIdx];
248         int64_t dur = slices->DursData()[sliceIdx];
249         int64_t endTs = startTs + dur;
250         if (dur == -1) {
251             incomplete = true;
252             continue;
253         }
254         if (incomplete) {
255             if (ts <= endTs) {
256                 continue;
257             }
258             for (int32_t j = stack.size() - 1; j > i; --j) {
259                 uint32_t childIdx = stack[i].index;
260                 slices->SetDur(childIdx, endTs - slices->TimeStampData()[childIdx]);
261                 stack.pop_back();
262             }
263             stack.pop_back();
264             incomplete = false;
265             continue;
266         }
267         if (endTs <= ts) {
268             stack.pop_back();
269         }
270     }
271 }
272 
MatchingIncompleteSliceIndex(const SlicesStack & stack,DataIndex category,DataIndex name)273 int32_t SliceFilter::MatchingIncompleteSliceIndex(const SlicesStack& stack, DataIndex category, DataIndex name)
274 {
275     auto slices = traceDataCache_->GetInternalSlicesData();
276     for (int32_t i = stack.size() - 1; i >= 0; i--) {
277         uint32_t sliceIdx = stack[i].index;
278         if (slices->DursData()[sliceIdx] != -1) {
279             continue;
280         }
281         const DataIndex& categoryLast = slices->CatsData()[sliceIdx];
282         if (category != INVALID_UINT64 && (categoryLast != INVALID_UINT64 && category != categoryLast)) {
283             continue;
284         }
285         const DataIndex& nameLast = slices->NamesData()[sliceIdx];
286         if (name != INVALID_UINT64 && nameLast != INVALID_UINT64 && name != nameLast) {
287             continue;
288         }
289         return static_cast<int32_t>(i);
290     }
291     return -1;
292 }
StartSlice(uint64_t timeStamp,uint32_t pid,DataIndex cat,DataIndex nameIndex,ArgsSet & args,SliceData sliceData)293 size_t SliceFilter::StartSlice(uint64_t timeStamp,
294                                uint32_t pid,
295                                DataIndex cat,
296                                DataIndex nameIndex,
297                                ArgsSet& args,
298                                SliceData sliceData)
299 {
300     InternalTid internalTid = sliceData.internalTid;
301     auto& sliceStack = binderStackMap_[internalTid];
302     auto& stack = sliceStack.sliceStack;
303     if (sliceStack.isAsyncEvent) {
304         sliceStack.asyncEventCount++;
305         sliceStack.asyncEventLastBeginTs = timeStamp;
306         if (!stack.empty()) {
307             return SIZE_MAX;
308         }
309     }
310     // keep slice of thread
311     CloseUnMatchedSlice(timeStamp, stack, internalTid);
312     uint32_t depth = stack.size();
313     auto slices = traceDataCache_->GetInternalSlicesData();
314     uint32_t parentId = depth == 0 ? INVALID_UINT32 : slices->IdsData()[stack.back().index];
315     size_t index = slices->AppendInternalSlice(sliceData.timeStamp, sliceData.duration, internalTid, sliceData.cat,
316                                                GetNameASCIISumNoNum(traceDataCache_->GetDataFromDict(sliceData.name)),
317                                                sliceData.name, 0, parentId);
318     if (depth >= std::numeric_limits<uint8_t>::max()) {
319         return SIZE_MAX;
320     }
321     slices->SetDepth(index, depth);
322 
323     uint32_t argSetId = INVALID_UINT32;
324     if (args.valuesMap_.size()) {
325         if (args.inserted_) {
326             argSetId = args.argSetId_;
327         } else {
328             argSetId = streamFilters_->argsFilter_->NewArgs(args);
329             sliceRowToArgsSetId_[index] = argSetId;
330             argsSetIdToSliceRow_[argSetId] = static_cast<uint32_t>(index);
331             args.argSetId_ = argSetId;
332             args.inserted_ = true;
333         }
334         // set ArgSetId here
335         slices->SetArgSetId(index, argSetId);
336     }
337     sliceData.argSetId = argSetId;
338     RememberSliceData(internalTid, binderStackMap_, sliceData, depth, index);
339     return index;
340 }
BeginBinder(uint64_t timeStamp,uint32_t pid,DataIndex cat,DataIndex nameIndex,ArgsSet args)341 size_t SliceFilter::BeginBinder(uint64_t timeStamp, uint32_t pid, DataIndex cat, DataIndex nameIndex, ArgsSet args)
342 {
343     InternalTid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(timeStamp, pid);
344     SliceData sliceData = {timeStamp, -1, internalTid, cat, nameIndex};
345     return StartSlice(timeStamp, pid, cat, nameIndex, args, std::move(sliceData));
346 }
347 
CompleteSlice(uint64_t timeStamp,uint32_t pid,uint32_t threadGroupId,DataIndex category,DataIndex name,ArgsSet args)348 size_t SliceFilter::CompleteSlice(uint64_t timeStamp,
349                                   uint32_t pid,
350                                   uint32_t threadGroupId,
351                                   DataIndex category,
352                                   DataIndex name,
353                                   ArgsSet args)
354 {
355     InternalTid internalTid = INVALID_ITID;
356     if (threadGroupId > 0) {
357         internalTid = streamFilters_->processFilter_->GetOrCreateThreadWithPid(pid, threadGroupId);
358     } else {
359         internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(timeStamp, pid);
360     }
361     TS_CHECK_TRUE_RET(binderStackMap_.find(internalTid) != binderStackMap_.end(), SIZE_MAX);
362     auto& stackInfo = binderStackMap_[internalTid];
363     SlicesStack& stack = stackInfo.sliceStack;
364     CloseUnMatchedSlice(timeStamp, stack, internalTid);
365     if (stack.empty()) {
366         callEventDisMatchCount_++;
367         return SIZE_MAX;
368     }
369     auto stackIdx = MatchingIncompleteSliceIndex(stack, category, name);
370     TS_CHECK_TRUE(stackIdx >= 0, SIZE_MAX, "MatchingIncompleteSliceIndex failed");
371     auto lastRow = stack[stackIdx].index;
372     auto slices = traceDataCache_->GetInternalSlicesData();
373     slices->SetDuration(lastRow, timeStamp);
374 
375     HandleAsyncEventAndOther(args, slices, lastRow, stackInfo);
376     if (stackIdx == stack.size() - 1) {
377         stack.pop_back();
378     }
379     streamFilters_->processFilter_->AddThreadSliceNum(internalTid);
380     return lastRow;
381 }
HandleAsyncEventAndOther(ArgsSet args,CallStack * slices,uint64_t lastRow,StackOfSlices & stackInfo)382 void SliceFilter::HandleAsyncEventAndOther(ArgsSet args, CallStack* slices, uint64_t lastRow, StackOfSlices& stackInfo)
383 {
384     auto argSize = sliceRowToArgsSetId_.count(lastRow);
385     size_t argSetId = 0;
386     if (args.valuesMap_.size()) {
387         if (!argSize) {
388             argSetId = streamFilters_->argsFilter_->NewArgs(args);
389             sliceRowToArgsSetId_[lastRow] = argSetId;
390             slices->SetArgSetId(lastRow, argSetId);
391         } else {
392             argSetId = sliceRowToArgsSetId_.at(lastRow);
393         }
394         streamFilters_->argsFilter_->AppendArgs(args, argSetId);
395     }
396     if (stackInfo.isAsyncEvent) {
397         ArgsSet args;
398         args.AppendArg(asyncBeginCountId_, BASE_DATA_TYPE_INT, stackInfo.asyncEventCount);
399         args.AppendArg(asyncBeginTsId_, BASE_DATA_TYPE_INT, stackInfo.asyncEventLastBeginTs);
400         if (!argSetId) {
401             argSetId = streamFilters_->argsFilter_->NewArgs(args);
402             sliceRowToArgsSetId_[lastRow] = argSetId;
403             slices->SetArgSetId(lastRow, argSetId);
404         } else {
405             streamFilters_->argsFilter_->AppendArgs(args, argSetId);
406         }
407     }
408 }
EndBinder(uint64_t timeStamp,uint32_t pid,DataIndex category,DataIndex name,ArgsSet args)409 size_t SliceFilter::EndBinder(uint64_t timeStamp, uint32_t pid, DataIndex category, DataIndex name, ArgsSet args)
410 {
411     return CompleteSlice(timeStamp, pid, 0, category, name, args);
412 }
AddArgs(uint32_t tid,DataIndex key1,DataIndex key2,ArgsSet & args)413 std::tuple<uint64_t, uint32_t> SliceFilter::AddArgs(uint32_t tid, DataIndex key1, DataIndex key2, ArgsSet& args)
414 {
415     InternalTid internalTid = streamFilters_->processFilter_->GetInternalTid(tid);
416     if (binderStackMap_.find(internalTid) == binderStackMap_.end()) {
417         return std::make_tuple(INVALID_UINT32, INVALID_UINT32);
418     }
419     auto& stack = binderStackMap_[internalTid];
420     auto idx = MatchingIncompleteSliceIndex(stack.sliceStack, key1, key2);
421     if (idx < 0) {
422         return std::make_tuple(INVALID_UINT32, INVALID_UINT32);
423     }
424     uint32_t argSetId = stack.sliceStack[idx].argSetId;
425     if (argSetId == INVALID_UINT32) {
426         argSetId = streamFilters_->argsFilter_->NewArgs(args);
427         sliceRowToArgsSetId_[stack.sliceStack[idx].index] = argSetId;
428         stack.sliceStack[idx].argSetId = argSetId;
429     } else {
430         streamFilters_->argsFilter_->AppendArgs(args, argSetId);
431     }
432     return std::make_tuple(stack.sliceStack[idx].index, argSetId);
433 }
StartAsyncSlice(uint64_t timeStamp,uint32_t pid,uint32_t threadGroupId,uint64_t cookie,DataIndex nameIndex)434 uint64_t SliceFilter::StartAsyncSlice(uint64_t timeStamp,
435                                       uint32_t pid,
436                                       uint32_t threadGroupId,
437                                       uint64_t cookie,
438                                       DataIndex nameIndex)
439 {
440     Unused(pid);
441     InternalPid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(timeStamp, threadGroupId);
442 
443     auto lastFilterId = asyncEventMap_.Find(internalTid, cookie, nameIndex);
444     auto slices = traceDataCache_->GetInternalSlicesData();
445     if (lastFilterId != INVALID_UINT64) {
446         asyncEventDisMatchCount_++;
447         return INVALID_UINT64;
448     }
449     asyncEventSize_++;
450     // a pid, cookie and function name determain a callstack
451     asyncEventMap_.Insert(internalTid, cookie, nameIndex, asyncEventSize_);
452     // the IDE need a depth to paint call slice in different position of the canvas, the depth of async call
453     // do not mean the parent-to-child relationship, it is different from no-async call
454     uint8_t depth = 0;
455     size_t index = slices->AppendInternalAsyncSlice(timeStamp, -1, internalTid, INVALID_UINT64,
456                                                     GetNameASCIISumNoNum(traceDataCache_->GetDataFromDict(nameIndex)),
457                                                     nameIndex, depth, cookie, std::nullopt);
458     asyncEventFilterMap_.insert(std::make_pair(asyncEventSize_, AsyncEvent{timeStamp, index}));
459     return index;
460 }
461 
FinishAsyncSlice(uint64_t timeStamp,uint32_t pid,uint32_t threadGroupId,uint64_t cookie,DataIndex nameIndex)462 uint64_t SliceFilter::FinishAsyncSlice(uint64_t timeStamp,
463                                        uint32_t pid,
464                                        uint32_t threadGroupId,
465                                        uint64_t cookie,
466                                        DataIndex nameIndex)
467 {
468     Unused(pid);
469     InternalPid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(timeStamp, threadGroupId);
470     auto lastFilterId = asyncEventMap_.Find(internalTid, cookie, nameIndex);
471     auto slices = traceDataCache_->GetInternalSlicesData();
472     if (lastFilterId == INVALID_UINT64) { // if failed
473         asyncEventDisMatchCount_++;
474         return INVALID_UINT64;
475     }
476     if (asyncEventFilterMap_.find(lastFilterId) == asyncEventFilterMap_.end()) {
477         TS_LOGE("logic error");
478         asyncEventDisMatchCount_++;
479         return INVALID_UINT64;
480     }
481     // update timeStamp
482     asyncEventFilterMap_.at(lastFilterId).timeStamp = timeStamp;
483     auto lastRow = asyncEventFilterMap_.at(lastFilterId).row;
484     slices->SetDuration(asyncEventFilterMap_.at(lastFilterId).row, timeStamp);
485     asyncEventFilterMap_.erase(lastFilterId);
486     asyncEventMap_.Erase(internalTid, cookie, nameIndex);
487     streamFilters_->processFilter_->AddThreadSliceNum(internalTid);
488     return lastRow;
489 }
490 
491 size_t
EndSlice(uint64_t timeStamp,uint32_t pid,uint32_t threadGroupId,DataIndex category,DataIndex name)492     SliceFilter::EndSlice(uint64_t timeStamp, uint32_t pid, uint32_t threadGroupId, DataIndex category, DataIndex name)
493 {
494     return CompleteSlice(timeStamp, pid, threadGroupId, category, name);
495 }
496 
Clear()497 void SliceFilter::Clear()
498 {
499     asyncEventMap_.Clear();
500     asyncNoEndingEventMap_.clear();
501     irqEventMap_.clear();
502     softIrqEventMap_.clear();
503     asyncEventFilterMap_.clear();
504     sliceStackMap_.clear();
505     depthHolder_.clear();
506     sliceRowToArgsSetId_.clear();
507     argsSetIdToSliceRow_.clear();
508     argsSetIdToSliceRow_.clear();
509     argsSet_.clear();
510 }
511 } // namespace TraceStreamer
512 } // namespace SysTuning
513