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