• 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 #include "ffrt_converter.h"
16 
17 namespace SysTuning {
18 namespace TraceStreamer {
RecoverTraceAndGenerateNewFile(const std::string & ffrtFileName,std::ofstream & outFile)19 bool FfrtConverter::RecoverTraceAndGenerateNewFile(const std::string &ffrtFileName, std::ofstream &outFile)
20 {
21     std::ifstream ffrtFile(ffrtFileName);
22     if (!ffrtFile.is_open() || !outFile.is_open()) {
23         TS_LOGE("ffrtFile or outFile is invalid.");
24         return false;
25     }
26     std::string line;
27     while (std::getline(ffrtFile, line))
28         context_.emplace_back(line);
29     ffrtFile.close();
30     InitTracingMarkerKey();
31     ClassifyContextForFfrtWorker();
32     ConvertFfrtThreadToFfrtTask();
33     for (const std::string &oneLine : context_) {
34         outFile << oneLine << std::endl;
35     }
36     Clear();
37     return true;
38 }
Clear()39 void FfrtConverter::Clear()
40 {
41     context_.clear();
42     ffrtPidMap_.clear();
43     taskLabels_.clear();
44 }
InitTracingMarkerKey()45 void FfrtConverter::InitTracingMarkerKey()
46 {
47     for (auto line : context_) {
48         if (line.find(" tracing_mark_write: ") != std::string::npos) {
49             tracingMarkerKey_ = "tracing_mark_write: ";
50             break;
51         }
52         if (line.find(" print: ") != std::string::npos) {
53             tracingMarkerKey_ = "print: ";
54             break;
55         }
56     }
57 }
ExtractProcessId(const size_t index)58 int FfrtConverter::ExtractProcessId(const size_t index)
59 {
60     std::smatch match;
61     static const std::regex pidPattern = std::regex(R"(\(\s*\d+\) \[)");
62     if (!std::regex_search(context_[index], match, pidPattern)) {
63         return 0;
64     }
65     for (size_t i = 0; i < match.size(); i++) {
66         if (match[i] == '-') {
67             return 0;
68         }
69     }
70     auto beginPos = match.str().find('(') + 1;
71     auto endPos = match.str().find(')');
72     return std::stoi(match.str().substr(beginPos, endPos - beginPos));
73 }
74 
ExtractTimeStr(const std::string & log)75 std::string FfrtConverter::ExtractTimeStr(const std::string &log)
76 {
77     std::smatch match;
78     static const std::regex timePattern = std::regex(R"( (\d+)\.(\d+):)");
79     if (std::regex_search(log, match, timePattern)) {
80         return match.str().substr(1, match.str().size() - STR_LEGH);
81     }
82     return "";
83 }
84 
ExtractCpuId(const std::string & log)85 std::string FfrtConverter::ExtractCpuId(const std::string &log)
86 {
87     std::smatch match;
88     static const std::regex cpuIdPattern = std::regex(R"(\) \[.*?\])");
89     if (std::regex_search(log, match, cpuIdPattern)) {
90         auto beginPos = match.str().find('[') + 1;
91         auto endPos = match.str().find(']');
92         return match.str().substr(beginPos, endPos - beginPos);
93     }
94     return "";
95 }
96 
MakeBeginFakeLog(const std::string & mark,const long long gid,const int prio,const ThreadInfo & threadInfo)97 std::string FfrtConverter::MakeBeginFakeLog(const std::string &mark,
98                                             const long long gid,
99                                             const int prio,
100                                             const ThreadInfo &threadInfo)
101 {
102     auto beginTimeStamp = ExtractTimeStr(mark);
103     auto cpuId = ExtractCpuId(mark);
104     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
105     auto taskId = GetTaskId(threadInfo.pid, gid);
106     (void)sprintf_s(
107         result.get(), MAX_LEN,
108         "\n  %s-%d    (%7d) [%s] ....   %s: sched_switch: prev_comm=%s prev_pid=%d prev_prio=%d prev_state=S ==> "
109         "next_comm=%s next_pid=%s next_prio=%d\n",
110         threadInfo.name.c_str(), threadInfo.tid, threadInfo.pid, cpuId.c_str(), beginTimeStamp.c_str(),
111         threadInfo.name.c_str(), threadInfo.tid, prio, taskLabels_[threadInfo.pid][gid].c_str(), taskId.c_str(), prio);
112     return mark + result.get();
113 }
114 
MakeEndFakeLog(const std::string & mark,const long long gid,const int prio,const ThreadInfo & threadInfo)115 std::string FfrtConverter::MakeEndFakeLog(const std::string &mark,
116                                           const long long gid,
117                                           const int prio,
118                                           const ThreadInfo &threadInfo)
119 {
120     auto endTimeStamp = ExtractTimeStr(mark);
121     auto cpuId = ExtractCpuId(mark);
122     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
123     auto taskId = GetTaskId(threadInfo.pid, gid);
124     (void)sprintf_s(
125         result.get(), MAX_LEN,
126         "  %s-%s    (%7d) [%s] ....   %s: sched_switch: prev_comm=%s prev_pid=%s prev_prio=%d prev_state=S ==> "
127         "next_comm=%s next_pid=%d next_prio=%d\n",
128         taskLabels_[threadInfo.pid][gid].c_str(), taskId.c_str(), threadInfo.pid, cpuId.c_str(), endTimeStamp.c_str(),
129         taskLabels_[threadInfo.pid][gid].c_str(), taskId.c_str(), prio, threadInfo.name.c_str(), threadInfo.tid, prio);
130     std::string fakeLog = result.get();
131     memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
132     return fakeLog;
133 }
134 
ReplaceSchedSwitchLog(std::string & fakeLog,const std::string & mark,const int pid,const long long gid,const int tid)135 std::string FfrtConverter::ReplaceSchedSwitchLog(std::string &fakeLog,
136                                                  const std::string &mark,
137                                                  const int pid,
138                                                  const long long gid,
139                                                  const int tid)
140 {
141     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
142     std::smatch match;
143     auto taskId = GetTaskId(pid, gid);
144     if (mark.find("prev_pid=" + std::to_string(tid)) != std::string::npos) {
145         if (regex_search(fakeLog, match, indexPattern_) && fakeLog.find("prev_comm=") != std::string::npos &&
146             fakeLog.find("prev_prio=") != std::string::npos) {
147             auto beginPos = fakeLog.find(match.str());
148             (void)sprintf_s(result.get(), MAX_LEN, "  %s-%s ", taskLabels_[pid][gid].c_str(), taskId.c_str());
149             fakeLog = result.get() + fakeLog.substr(beginPos);
150             size_t pcommPos = fakeLog.find("prev_comm=");
151             size_t pPidPos = fakeLog.find("prev_pid=");
152             memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
153             (void)sprintf_s(result.get(), MAX_LEN, "prev_comm=%s ", taskLabels_[pid][gid].c_str());
154             fakeLog = fakeLog.substr(0, pcommPos) + result.get() + fakeLog.substr(pPidPos);
155             memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
156             pPidPos = fakeLog.find("prev_pid=");
157             size_t pPrioPos = fakeLog.find("prev_prio=");
158             (void)sprintf_s(result.get(), MAX_LEN, "prev_pid=%s ", taskId.c_str());
159             fakeLog = fakeLog.substr(0, pPidPos) + result.get() + fakeLog.substr(pPrioPos);
160             memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
161         }
162     } else if (mark.find("next_pid=" + std::to_string(tid)) != std::string::npos &&
163                fakeLog.find("next_comm=") != std::string::npos && fakeLog.find("next_prio=") != std::string::npos) {
164         (void)sprintf_s(result.get(), MAX_LEN, "next_comm=%s ", taskLabels_[pid][gid].c_str());
165         size_t nCommPos = fakeLog.find("next_comm=");
166         size_t nPidPos = fakeLog.find("next_pid=");
167         fakeLog = fakeLog.substr(0, nCommPos) + result.get() + fakeLog.substr(nPidPos);
168         memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
169         (void)sprintf_s(result.get(), MAX_LEN, "next_pid=%s ", taskId.c_str());
170         nPidPos = fakeLog.find("next_pid=");
171         size_t nPrioPos = fakeLog.find("next_prio=");
172         fakeLog = fakeLog.substr(0, nPidPos) + result.get() + fakeLog.substr(nPrioPos);
173     }
174     return fakeLog;
175 }
176 
ReplaceSchedWakeLog(std::string & fakeLog,const std::string & label,const int pid,const long long gid)177 std::string FfrtConverter::ReplaceSchedWakeLog(std::string &fakeLog,
178                                                const std::string &label,
179                                                const int pid,
180                                                const long long gid)
181 {
182     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
183     auto taskId = GetTaskId(pid, gid);
184     (void)sprintf_s(result.get(), MAX_LEN, "comm=%s ", label.c_str());
185     size_t commPos = fakeLog.find("comm=");
186     size_t pidPos = fakeLog.find("pid=");
187     if (commPos != std::string::npos && pidPos != std::string::npos) {
188         fakeLog = fakeLog.substr(0, commPos) + result.get() + fakeLog.substr(pidPos);
189         memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
190         (void)sprintf_s(result.get(), MAX_LEN, "pid=%s ", taskId.c_str());
191         pidPos = fakeLog.find("pid=");
192         size_t prioPos = fakeLog.find("prio=");
193         if (prioPos != std::string::npos) {
194             fakeLog = fakeLog.substr(0, pidPos) + result.get() + fakeLog.substr(prioPos);
195         }
196     }
197     return fakeLog;
198 }
199 
ReplaceSchedBlockLog(std::string & fakeLog,const int pid,const long long gid)200 std::string FfrtConverter::ReplaceSchedBlockLog(std::string &fakeLog, const int pid, const long long gid)
201 {
202     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
203     auto taskId = GetTaskId(pid, gid);
204     (void)sprintf_s(result.get(), MAX_LEN, "pid=%s ", taskId.c_str());
205     size_t pidPos = fakeLog.find("pid");
206     size_t ioPos = fakeLog.find("iowait=");
207     if (pidPos != std::string::npos && ioPos != std::string::npos) {
208         fakeLog = fakeLog.substr(0, pidPos) + result.get() + fakeLog.substr(ioPos);
209     }
210     return fakeLog;
211 }
ReplaceTracingMarkLog(std::string & fakeLog,const std::string & label,const int pid,const long long gid)212 std::string FfrtConverter::ReplaceTracingMarkLog(std::string &fakeLog,
213                                                  const std::string &label,
214                                                  const int pid,
215                                                  const long long gid)
216 {
217     std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
218     std::smatch match;
219     auto taskId = GetTaskId(pid, gid);
220     if (regex_search(fakeLog, match, indexPattern_)) {
221         auto beginPos = fakeLog.find(match.str());
222         (void)sprintf_s(result.get(), MAX_LEN, "  %s-%s ", label.c_str(), taskId.c_str());
223         fakeLog = result.get() + fakeLog.substr(beginPos);
224     }
225     return fakeLog;
226 }
ConvertWorkerLogToTask(const std::string & mark,const int pid,const long long gid,const int tid)227 std::string FfrtConverter::ConvertWorkerLogToTask(const std::string &mark,
228                                                   const int pid,
229                                                   const long long gid,
230                                                   const int tid)
231 {
232     std::string fakeLog = mark;
233     if (mark.find("sched_switch: ") != std::string::npos) {
234         return ReplaceSchedSwitchLog(fakeLog, mark, pid, gid, tid);
235     }
236     if (mark.find(": sched_wak") != std::string::npos) {
237         return ReplaceSchedWakeLog(fakeLog, taskLabels_[pid][gid], pid, gid);
238     }
239     if (mark.find("sched_blocked_reason: ") != std::string::npos) {
240         return ReplaceSchedBlockLog(fakeLog, pid, gid);
241     }
242     return ReplaceTracingMarkLog(fakeLog, taskLabels_[pid][gid], pid, gid);
243 }
FindIntNumberAfterStr(const size_t index,const string & str)244 int FfrtConverter::FindIntNumberAfterStr(const size_t index, const string &str)
245 {
246     auto beginPos = context_[index].find(str);
247     if (beginPos != std::string::npos) {
248         beginPos = beginPos + str.length();
249         auto endPos = context_[index].find_first_of(" ", beginPos);
250         return stoi(context_[index].substr(beginPos, endPos - beginPos));
251     }
252     return -1;
253 }
FindSubStrAfterStr(const size_t index,const string & str)254 std::string FfrtConverter::FindSubStrAfterStr(const size_t index, const string &str)
255 {
256     auto beginPos = context_[index].find(str) + str.length();
257     auto endPos = context_[index].find_first_of(" ", beginPos);
258     return context_[index].substr(beginPos, endPos - beginPos);
259 }
ClassifySchedSwitchData(const size_t index,std::unordered_map<int,std::vector<int>> & traceMap)260 void FfrtConverter::ClassifySchedSwitchData(const size_t index, std::unordered_map<int, std::vector<int>> &traceMap)
261 {
262     auto prevTid = FindIntNumberAfterStr(index, "prev_pid=");
263     auto nextTid = FindIntNumberAfterStr(index, "next_pid=");
264     // update sched_switch prev_pid and next_pid corresponding line number
265     if (prevTid != -1 && traceMap.count(prevTid) == 0) {
266         traceMap[prevTid] = std::vector<int>();
267     }
268     if (nextTid != -1 && traceMap.count(nextTid) == 0) {
269         traceMap[nextTid] = std::vector<int>();
270     }
271     traceMap[prevTid].push_back(index);
272     traceMap[nextTid].push_back(index);
273 
274     // Get thread name as ffrtxxx or OS_FFRTxxx
275     if (context_[index].find("prev_comm=ffrt") != std::string::npos ||
276         context_[index].find("prev_comm=OS_FFRT") != std::string::npos) {
277         auto pid = ExtractProcessId(index);
278         if (ffrtPidMap_.count(pid) == 0 || ffrtPidMap_[pid].count(prevTid) == 0) {
279             ffrtPidMap_[pid][prevTid].name = FindSubStrAfterStr(index, "prev_comm=");
280         }
281     }
282     return;
283 }
FindFfrtProcessAndClassify(const size_t index,std::unordered_map<int,std::vector<int>> & traceMap)284 void FfrtConverter::FindFfrtProcessAndClassify(const size_t index, std::unordered_map<int, std::vector<int>> &traceMap)
285 {
286     if (context_[index].find("sched_switch") != std::string::npos) {
287         ClassifySchedSwitchData(index, traceMap);
288         return;
289     }
290     if (context_[index].find(": sched_wak") != std::string::npos ||
291         (context_[index].find("sched_blocked_reason:") != std::string::npos)) {
292         auto tid = FindIntNumberAfterStr(index, "pid=");
293         if (traceMap.find(tid) == traceMap.end()) {
294             traceMap[tid] = std::vector<int>();
295         }
296         traceMap[tid].push_back(index);
297         return;
298     }
299     static std::smatch match;
300     if (std::regex_search(context_[index], match, matchPattern_)) {
301         auto endPos = context_[index].find(match.str());
302         std::string res = context_[index].substr(0, endPos);
303         std::string begin = "-";
304         auto beginPos = res.find_last_of(begin);
305         if (beginPos != std::string::npos) {
306             beginPos = beginPos + begin.length();
307             auto tid = stoi(context_[index].substr(beginPos, endPos - beginPos));
308             if (traceMap.find(tid) == traceMap.end()) {
309                 traceMap[tid] = std::vector<int>();
310             }
311             traceMap[tid].push_back(index);
312         }
313     }
314     return;
315 }
316 
GetTaskId(int pid,long long gid)317 std::string FfrtConverter::GetTaskId(int pid, long long gid)
318 {
319     stringstream ss;
320     ss << pid << "0" << gid;
321     auto str = ss.str();
322     while (str.size() > uint32MaxLength_) {
323         str.erase(0, 1);
324     }
325     auto result = stoll(str);
326     if (result > INVALID_UINT32) {
327         str.erase(0, 1);
328     }
329     return str;
330 }
331 
IsDigit(const std::string & str)332 bool FfrtConverter::IsDigit(const std::string &str)
333 {
334     auto endPos = str.find_last_not_of(" ");
335     string newStr = str;
336     newStr.erase(endPos + 1);
337     if (newStr.back() == '\r') {
338         newStr.pop_back();
339     }
340     for (int i = 0; i < newStr.length(); i++) {
341         if (!std::isdigit(newStr[i])) {
342             return false;
343         }
344     }
345     return true;
346 }
347 
ClassifyContextForFfrtWorker()348 void FfrtConverter::ClassifyContextForFfrtWorker()
349 {
350     std::unordered_map<int, std::vector<int>> traceMap;
351     for (auto index = 0; index < context_.size(); index++) {
352         FindFfrtProcessAndClassify(index, traceMap);
353     }
354     for (auto &[pid, threads] : ffrtPidMap_) {
355         for (const auto &thread : threads) {
356             auto tid = thread.first;
357             ffrtPidMap_[pid][tid].indices = traceMap[tid];
358         }
359     }
360 }
ConvertFfrtThreadToFfrtTask()361 void FfrtConverter::ConvertFfrtThreadToFfrtTask()
362 {
363     int prio;
364     for (auto &[pid, threads] : ffrtPidMap_) {
365         taskLabels_[pid] = {};
366         for (auto &[tid, ffrtContent] : ffrtPidMap_[pid]) {
367             ThreadInfo threadInfo;
368             threadInfo.pid = pid;
369             threadInfo.tid = tid;
370             threadInfo.name = ffrtContent.name;
371             auto switchInFakeLog = false;
372             auto switchOutFakeLog = false;
373             auto ffbkMarkRemove = false;
374             auto gid = WAKE_EVENT_DEFAULT_VALUE;
375             for (auto index : ffrtContent.indices) {
376                 ProcessMarkWithSchedSwitch(tid, prio, index);
377                 if (context_[index].find("|FFRT") != std::string::npos ||
378                     context_[index].find("|H:FFRT") != std::string::npos) {
379                     if (!ProcessMarkWithFFRT(index, prio, gid, threadInfo)) {
380                         continue;
381                     }
382                     switchInFakeLog = true;
383                     continue;
384                 }
385                 if (gid != WAKE_EVENT_DEFAULT_VALUE) {
386                     if (!DeleteRedundance(switchInFakeLog, switchOutFakeLog, index)) {
387                         continue;
388                     }
389                     static const std::regex EndPattern = std::regex(R"( F\|(\d+)\|[BF]\|(\d+))");
390                     static const std::regex HEndPattern = std::regex(R"( F\|(\d+)\|H:[BF]\s(\d+))");
391                     if (std::regex_search(context_[index], EndPattern) ||
392                         std::regex_search(context_[index], HEndPattern)) {
393                         context_[index] = MakeEndFakeLog(context_[index], gid, prio, threadInfo);
394                         gid = WAKE_EVENT_DEFAULT_VALUE;
395                         switchOutFakeLog = false;
396                         continue;
397                     }
398                     context_[index] = ConvertWorkerLogToTask(context_[index], pid, gid, tid);
399                     continue;
400                 }
401             }
402         }
403     }
404 }
ProcessMarkWithSchedSwitch(const int tid,int & prio,const size_t index)405 void FfrtConverter::ProcessMarkWithSchedSwitch(const int tid, int &prio, const size_t index)
406 {
407     if (context_[index].find("sched_switch:") != std::string::npos) {
408         if (context_[index].find("prev_pid=" + std::to_string(tid) + " ") != std::string::npos) {
409             static std::string beginPprio = "prev_prio=";
410             auto beginPos = context_[index].find(beginPprio);
411             if (beginPos != std::string::npos) {
412                 beginPos = beginPos + beginPprio.length();
413                 auto endPos = context_[index].find_first_of(" ", beginPos);
414                 prio = stoi(context_[index].substr(beginPos, endPos - beginPos));
415             }
416         } else if (context_[index].find("next_pid=" + std::to_string(tid)) != std::string::npos) {
417             static std::string beginNprio = "next_prio=";
418             auto beginPos = context_[index].find(beginNprio);
419             if (beginPos != std::string::npos) {
420                 beginPos = beginPos + beginNprio.length();
421                 prio = stoi(context_[index].substr(beginPos));
422             }
423         }
424     }
425 }
GetLabel(const string & line)426 std::string FfrtConverter::GetLabel(const string &line)
427 {
428     std::string label;
429     if (line.find("|H:FFRT") != std::string::npos) {
430         if (line.find("H:FFRT::") != std::string::npos) {
431             auto beginPos = line.rfind("[");
432             auto endPos = line.rfind("]");
433             if (beginPos != std::string::npos && endPos != std::string::npos) {
434                 label = line.substr(beginPos + 1, endPos - beginPos - 1);
435             }
436         } else {
437             static std::string indexHFfrt = "|H:FFRT";
438             auto beginPos = line.find(indexHFfrt);
439             beginPos = beginPos + indexHFfrt.length();
440             auto endPos = line.find_first_of("|", beginPos);
441             if (endPos != std::string::npos) {
442                 label = line.substr(beginPos, endPos - beginPos);
443             }
444         }
445     } else {
446         if (line.find("|FFRT::") != std::string::npos) {
447             auto beginPos = line.rfind("[");
448             auto endPos = line.rfind("]");
449             if (beginPos != std::string::npos && endPos != std::string::npos) {
450                 label = line.substr(beginPos + 1, endPos - beginPos - 1);
451             }
452         } else {
453             static std::string indexFfrt = "|FFRT";
454             auto beginPos = line.find(indexFfrt);
455             beginPos = beginPos + indexFfrt.length();
456             auto endPos = line.find_first_of("|", beginPos);
457             if (endPos != std::string::npos) {
458                 label = line.substr(beginPos, endPos - beginPos);
459             }
460         }
461     }
462     return label;
463 }
ProcessMarkWithFFRT(const int index,int & prio,int32_t & gid,const ThreadInfo & threadInfo)464 bool FfrtConverter::ProcessMarkWithFFRT(const int index, int &prio, int32_t &gid, const ThreadInfo &threadInfo)
465 {
466     auto line = context_[index];
467     auto label = GetLabel(line);
468     if (label.find("executor_task") != std::string::npos || label.find("ex_task") != std::string::npos) {
469         return false;
470     }
471     std::string missLog;
472     if (gid != WAKE_EVENT_DEFAULT_VALUE) {
473         missLog = MakeEndFakeLog(line, gid, prio, threadInfo);
474         auto timestamp = ExtractTimeStr(line);
475         auto cpuId = ExtractCpuId(line);
476         std::unique_ptr<char[]> result = std::make_unique<char[]>(MAX_LEN);
477         (void)sprintf_s(result.get(), MAX_LEN, "  %s-%d    (%7d) [%s] ....   %s: %sE|%d\n", threadInfo.name.c_str(),
478                         threadInfo.tid, threadInfo.pid, cpuId.c_str(), timestamp.c_str(), tracingMarkerKey_.c_str(),
479                         threadInfo.pid);
480         missLog = missLog + result.get();
481         memset_s(result.get(), MAX_LEN, 0, MAX_LEN);
482     }
483     auto beginPos = line.rfind("|");
484     if (beginPos == std::string::npos || !IsDigit(line.substr(beginPos + 1))) {
485         return false;
486     }
487     gid = stoll(line.substr(beginPos + 1));
488     if (taskLabels_[threadInfo.pid].count(gid) == 0) {
489         taskLabels_[threadInfo.pid][gid] = label;
490     }
491     context_[index] = MakeBeginFakeLog(line, gid, prio, threadInfo);
492     if (!missLog.empty()) {
493         context_[index] = missLog + context_[index];
494     }
495     return true;
496 }
DeleteRedundance(bool & switchInFakeLog,bool & switchOutFakeLog,const int index)497 bool FfrtConverter::DeleteRedundance(bool &switchInFakeLog, bool &switchOutFakeLog, const int index)
498 {
499     static const std::regex CoPattern = std::regex(R"( F\|(\d+)\|Co\|(\d+))");
500     static const std::regex HCoPattern = std::regex(R"( F\|(\d+)\|H:Co\s(\d+))");
501     if (std::regex_search(context_[index], CoPattern) || std::regex_search(context_[index], HCoPattern)) {
502         context_[index].clear();
503         if (switchInFakeLog) {
504             switchInFakeLog = false;
505             return false;
506         } else {
507             switchOutFakeLog = true;
508             return false;
509         }
510     }
511     if (switchInFakeLog && (context_[index].find(tracingMarkerKey_ + "B") != std::string::npos)) {
512         context_[index].clear();
513         return false;
514     }
515     if (switchOutFakeLog && (context_[index].find(tracingMarkerKey_ + "E") != std::string::npos)) {
516         context_[index].clear();
517         return false;
518     }
519     return true;
520 }
521 } // namespace TraceStreamer
522 } // namespace SysTuning
523