1 /*
2 * Copyright (c) 2023 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 #include "dfx/trace_record/ffrt_trace_record.h"
16 #include <securec.h>
17 #include <sstream>
18 #include <fcntl.h>
19 #include <iomanip>
20 #include <sys/syscall.h>
21 #include <unistd.h>
22 #include "dfx/bbox/bbox.h"
23
24 namespace ffrt {
25 const int COLUMN_WIDTH_3 = 3;
26 const int COLUMN_WIDTH_9 = 9;
27 const int COLUMN_WIDTH_10 = 10;
28 const int COLUMN_WIDTH_12 = 12;
29 const int COLUMN_WIDTH_13 = 13;
30 const int COLUMN_WIDTH_16 = 16;
31 const int COLUMN_WIDTH_18 = 18;
32 const int COLUMN_WIDTH_19 = 19;
33 const int COLUMN_WIDTH_22 = 22;
34 bool FFRTTraceRecord::ffrt_be_used_ = false;
35 int FFRTTraceRecord::g_recordMaxWorkerNumber_[QoS::MaxNum()] = {};
36 ffrt_record_task_counter_t FFRTTraceRecord::g_recordTaskCounter_[FFRTTraceRecord::TASK_TYPE_NUM][QoS::MaxNum()] = {};
37 ffrt_record_task_time_t FFRTTraceRecord::g_recordTaskTime_[FFRTTraceRecord::TASK_TYPE_NUM][QoS::MaxNum()] = {};
38
39 #if (FFRT_TRACE_RECORD_LEVEL >= FFRT_TRACE_RECORD_LEVEL_2)
DumpNormalTaskStatisticInfo(std::ostringstream & oss)40 void FFRTTraceRecord::DumpNormalTaskStatisticInfo(std::ostringstream& oss)
41 {
42 for (size_t i = 0; i < QoS::MaxNum(); i++) {
43 if (g_recordTaskCounter_[ffrt_normal_task][i].submitCounter <= 0) {
44 continue;
45 }
46 oss << std::setw(COLUMN_WIDTH_3) << i
47 << std::setw(COLUMN_WIDTH_9) << "normal"
48 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_normal_task][i].submitCounter
49 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_normal_task][i].enqueueCounter
50 << std::setw(COLUMN_WIDTH_12) << g_recordTaskCounter_[ffrt_normal_task][i].coSwitchCounter
51 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_normal_task][i].doneCounter
52 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_normal_task][i].doneCounter;
53 #if (FFRT_TRACE_RECORD_LEVEL >= FFRT_TRACE_RECORD_LEVEL_3)
54 unsigned int doneCount = g_recordTaskCounter_[ffrt_normal_task][i].doneCounter.load();
55 if (doneCount > 0) {
56 oss << std::setw(COLUMN_WIDTH_13) << g_recordMaxWorkerNumber_[i]
57 << std::setw(COLUMN_WIDTH_16) << g_recordTaskTime_[ffrt_normal_task][i].maxWaitTime
58 << std::setw(COLUMN_WIDTH_19) << g_recordTaskTime_[ffrt_normal_task][i].maxRunDuration
59 << std::setw(COLUMN_WIDTH_16) << (g_recordTaskTime_[ffrt_normal_task][i].waitTime/doneCount)
60 << std::setw(COLUMN_WIDTH_19) << (g_recordTaskTime_[ffrt_normal_task][i].runDuration/doneCount)
61 << std::setw(COLUMN_WIDTH_18) << g_recordTaskTime_[ffrt_normal_task][i].waitTime
62 << std::setw(COLUMN_WIDTH_22) << g_recordTaskTime_[ffrt_normal_task][i].runDuration;
63 }
64 #endif
65 oss << "\n";
66 }
67 }
68
DumpQueueTaskStatisticInfo(std::ostringstream & oss)69 void FFRTTraceRecord::DumpQueueTaskStatisticInfo(std::ostringstream& oss)
70 {
71 for (size_t i = 0; i < QoS::MaxNum(); i++) {
72 if (g_recordTaskCounter_[ffrt_queue_task][i].submitCounter <= 0) {
73 continue;
74 }
75 oss << std::setw(COLUMN_WIDTH_3) << i
76 << std::setw(COLUMN_WIDTH_9) << "queue"
77 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_queue_task][i].submitCounter
78 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_queue_task][i].submitCounter
79 << std::setw(COLUMN_WIDTH_12) << g_recordTaskCounter_[ffrt_queue_task][i].coSwitchCounter
80 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_queue_task][i].doneCounter
81 << std::setw(COLUMN_WIDTH_10) << (g_recordTaskCounter_[ffrt_queue_task][i].doneCounter +
82 g_recordTaskCounter_[ffrt_queue_task][i].cancelCounter);
83 #if (FFRT_TRACE_RECORD_LEVEL >= FFRT_TRACE_RECORD_LEVEL_3)
84 unsigned int doneCount = g_recordTaskCounter_[ffrt_queue_task][i].doneCounter.load();
85 if (doneCount > 0) {
86 oss << std::setw(COLUMN_WIDTH_13) << g_recordMaxWorkerNumber_[i]
87 << std::setw(COLUMN_WIDTH_16) << g_recordTaskTime_[ffrt_queue_task][i].maxWaitTime
88 << std::setw(COLUMN_WIDTH_19) << g_recordTaskTime_[ffrt_queue_task][i].maxRunDuration
89 << std::setw(COLUMN_WIDTH_16) << (g_recordTaskTime_[ffrt_queue_task][i].waitTime/doneCount)
90 << std::setw(COLUMN_WIDTH_19) << (g_recordTaskTime_[ffrt_queue_task][i].runDuration/doneCount)
91 << std::setw(COLUMN_WIDTH_18) << g_recordTaskTime_[ffrt_queue_task][i].waitTime
92 << std::setw(COLUMN_WIDTH_22) << g_recordTaskTime_[ffrt_queue_task][i].runDuration;
93 }
94 #endif
95 oss << "\n";
96 }
97 }
98
DumpUVTaskStatisticInfo(std::ostringstream & oss)99 void FFRTTraceRecord::DumpUVTaskStatisticInfo(std::ostringstream& oss)
100 {
101 for (size_t i = 0; i < QoS::MaxNum(); i++) {
102 if (g_recordTaskCounter_[ffrt_uv_task][i].submitCounter <= 0) {
103 continue;
104 }
105 oss << std::setw(COLUMN_WIDTH_3) << i
106 << std::setw(COLUMN_WIDTH_9) << "uv"
107 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_uv_task][i].submitCounter
108 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_uv_task][i].enqueueCounter
109 << std::setw(COLUMN_WIDTH_12) << 0
110 << std::setw(COLUMN_WIDTH_10) << g_recordTaskCounter_[ffrt_uv_task][i].doneCounter
111 << std::setw(COLUMN_WIDTH_10) << (g_recordTaskCounter_[ffrt_uv_task][i].doneCounter +
112 g_recordTaskCounter_[ffrt_uv_task][i].cancelCounter);
113 oss << "\n";
114 }
115 }
116
StatisticInfoDump(char * buf,uint32_t len)117 int FFRTTraceRecord::StatisticInfoDump(char* buf, uint32_t len)
118 {
119 std::ostringstream oss;
120 oss << "---\n" << "Qos TaskType SubmitNum EnueueNum CoSwitchNum DoneNum FinishNum";
121 #if (FFRT_TRACE_RECORD_LEVEL >= FFRT_TRACE_RECORD_LEVEL_3)
122 oss << " MaxWorkerNum MaxWaitTime(us) MaxRunDuration(us) AvgWaitTime(us) AvgRunDuration(us) TotalWaitTime(us)"
123 << " TotalRunDuration(us)";
124 #endif
125 oss << "\n";
126 DumpNormalTaskStatisticInfo(oss);
127 DumpQueueTaskStatisticInfo(oss);
128 DumpUVTaskStatisticInfo(oss);
129 oss << "---\n";
130 return snprintf_s(buf, len, len - 1, "%s", oss.str().c_str());
131 }
132
GetSubmitCount()133 unsigned int FFRTTraceRecord::GetSubmitCount()
134 {
135 int maxQos = QoS::MaxNum();
136 unsigned int totalCount = 0;
137 for (int i = 0; i < maxQos; i++) {
138 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].submitCounter;
139 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].submitCounter;
140 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].submitCounter;
141 }
142 return totalCount;
143 }
144
GetEnqueueCount()145 unsigned int FFRTTraceRecord::GetEnqueueCount()
146 {
147 int maxQos = QoS::MaxNum();
148 unsigned int totalCount = 0;
149 for (int i = 0; i < maxQos; i++) {
150 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].enqueueCounter;
151 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].enqueueCounter;
152 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].enqueueCounter;
153 }
154 return totalCount;
155 }
156
GetRunCount()157 unsigned int FFRTTraceRecord::GetRunCount()
158 {
159 int maxQos = QoS::MaxNum();
160 unsigned int totalCount = 0;
161 for (int i = 0; i < maxQos; i++) {
162 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].runCounter;
163 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].runCounter;
164 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].runCounter;
165 }
166 return totalCount;
167 }
168
GetDoneCount()169 unsigned int FFRTTraceRecord::GetDoneCount()
170 {
171 int maxQos = QoS::MaxNum();
172 unsigned int totalCount = 0;
173 for (int i = 0; i < maxQos; i++) {
174 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].doneCounter;
175 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].doneCounter;
176 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].doneCounter;
177 }
178 return totalCount;
179 }
180
GetCoSwitchCount()181 unsigned int FFRTTraceRecord::GetCoSwitchCount()
182 {
183 int maxQos = QoS::MaxNum();
184 unsigned int totalCount = 0;
185 for (int i = 0; i < maxQos; i++) {
186 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].coSwitchCounter;
187 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].coSwitchCounter;
188 }
189 return totalCount;
190 }
191
GetFinishCount()192 unsigned int FFRTTraceRecord::GetFinishCount()
193 {
194 int maxQos = QoS::MaxNum();
195 unsigned int totalCount = 0;
196 for (int i = 0; i < maxQos; i++) {
197 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].doneCounter;
198 totalCount += g_recordTaskCounter_[ffrt_normal_task][i].cancelCounter;
199 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].doneCounter;
200 totalCount += g_recordTaskCounter_[ffrt_uv_task][i].cancelCounter;
201 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].doneCounter;
202 totalCount += g_recordTaskCounter_[ffrt_queue_task][i].cancelCounter;
203 }
204 return totalCount;
205 }
206 #endif // FFRT_TRACE_RECORD_LEVEL >= FFRT_TRACE_RECORD_LEVEL_2
207 }