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