1 /*
2 * Copyright (c) 2022 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 "rtg_interface.h"
17 #include <sys/ioctl.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <securec.h>
21 #include <cstdio>
22 #include <string>
23 #include <vector>
24 #include <cerrno>
25 #include "bits/ioctl.h"
26 #include "rme_log_domain.h"
27
28 namespace OHOS {
29 namespace RME {
30 namespace {
31 constexpr size_t MAX_LENGTH = 100;
32 constexpr size_t MAX_STR_LEN = 100;
33 constexpr int RTG_TYPE_MAX = 3;
34 }
35 DEFINE_RMELOG_INTELLISENSE("rtg_interface");
36
37 const char RTG_SCHED_IPC_MAGIC = 0xAB;
38
39 #define CMD_ID_SET_ENABLE \
40 _IOWR(RTG_SCHED_IPC_MAGIC, SET_ENABLE, struct rtg_enable_data)
41 #define CMD_ID_SET_RTG \
42 _IOWR(RTG_SCHED_IPC_MAGIC, SET_RTG, struct rtg_str_data)
43 #define CMD_ID_SET_CONFIG \
44 _IOWR(RTG_SCHED_IPC_MAGIC, SET_CONFIG, struct rtg_str_data)
45 #define CMD_ID_SET_RTG_ATTR \
46 _IOWR(RTG_SCHED_IPC_MAGIC, SET_RTG_ATTR, struct rtg_str_data)
47 #define CMD_ID_BEGIN_FRAME_FREQ \
48 _IOWR(RTG_SCHED_IPC_MAGIC, BEGIN_FRAME_FREQ, struct proc_state_data)
49 #define CMD_ID_END_FRAME_FREQ \
50 _IOWR(RTG_SCHED_IPC_MAGIC, END_FRAME_FREQ, struct proc_state_data)
51 #define CMD_ID_END_SCENE \
52 _IOWR(RTG_SCHED_IPC_MAGIC, END_SCENE, struct proc_state_data)
53 #define CMD_ID_SET_MIN_UTIL \
54 _IOWR(RTG_SCHED_IPC_MAGIC, SET_MIN_UTIL, struct proc_state_data)
55 #define CMD_ID_SET_MARGIN \
56 _IOWR(RTG_SCHED_IPC_MAGIC, SET_MARGIN, struct proc_state_data)
57 #define CMD_ID_LIST_RTG \
58 _IOWR(RTG_SCHED_IPC_MAGIC, LIST_RTG, struct rtg_info)
59 #define CMD_ID_LIST_RTG_THREAD \
60 _IOWR(RTG_SCHED_IPC_MAGIC, LIST_RTG_THREAD, struct rtg_grp_data)
61 #define CMD_ID_SEARCH_RTG \
62 _IOWR(RTG_SCHED_IPC_MAGIC, SEARCH_RTG, struct proc_state_data)
63 #define CMD_ID_GET_ENABLE \
64 _IOWR(RTG_SCHED_IPC_MAGIC, GET_ENABLE, struct rtg_enable_data)
65
BasicOpenRtgNode()66 int BasicOpenRtgNode()
67 {
68 char fileName[] = "/proc/self/sched_rtg_ctrl";
69 int fd = open(fileName, O_RDWR);
70 return fd;
71 }
72
EnableRtg(bool flag)73 int EnableRtg(bool flag)
74 {
75 struct rtg_enable_data enableData;
76 char configStr[] = "load_freq_switch:1;sched_cycle:1";
77
78 enableData.enable = flag;
79 enableData.len = sizeof(configStr);
80 enableData.data = configStr;
81 int fd = BasicOpenRtgNode();
82 if (fd < 0) {
83 return fd;
84 }
85 if (ioctl(fd, CMD_ID_SET_ENABLE, &enableData)) {
86 RME_LOGE("set rtg config enable failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
87 } else {
88 RME_LOGI("set rtg config enable success.");
89 }
90 close(fd);
91 return 0;
92 };
93
CreateNewRtgGrp(int prioType,int rtNum)94 int CreateNewRtgGrp(int prioType, int rtNum)
95 {
96 struct rtg_grp_data grp_data;
97 int ret;
98 int fd = BasicOpenRtgNode();
99 if (fd < 0) {
100 return fd;
101 }
102 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
103 if ((prioType > 0) && (prioType < RTG_TYPE_MAX)) {
104 grp_data.prio_type = prioType;
105 }
106 if (rtNum > 0) {
107 grp_data.rt_cnt = rtNum;
108 }
109 grp_data.rtg_cmd = CMD_CREATE_RTG_GRP;
110 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
111 if (ret < 0) {
112 RME_LOGE("create rtg grp failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
113 } else {
114 RME_LOGI("create rtg grp success, get rtg id %{public}d.", ret);
115 }
116 close(fd);
117 return ret;
118 }
119
AddThreadToRtg(int tid,int grpId,int prioType)120 int AddThreadToRtg(int tid, int grpId, int prioType)
121 {
122 struct rtg_grp_data grp_data;
123 int ret;
124 int fd = BasicOpenRtgNode();
125 if (fd < 0) {
126 RME_LOGE("open node failed.");
127 return fd;
128 }
129 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
130 grp_data.tid_num = 1;
131 grp_data.tids[0] = tid;
132 grp_data.grp_id = grpId;
133 grp_data.rtg_cmd = CMD_ADD_RTG_THREAD;
134 grp_data.prio_type = prioType;
135 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
136 close(fd);
137 return ret;
138 }
139
AddThreadsToRtg(vector<int> tids,int grpId,int prioType)140 int AddThreadsToRtg(vector<int> tids, int grpId, int prioType)
141 {
142 struct rtg_grp_data grp_data;
143 int ret;
144 int fd = BasicOpenRtgNode();
145 if (fd < 0) {
146 return fd;
147 }
148 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
149 int num = static_cast<int>(tids.size());
150 if (num > MAX_TID_NUM) {
151 return -1;
152 }
153 grp_data.tid_num = num;
154 grp_data.grp_id = grpId;
155 grp_data.rtg_cmd = CMD_ADD_RTG_THREAD;
156 grp_data.prio_type = prioType;
157 for (int i = 0; i < num; i++) {
158 if (tids[i] < 0) {
159 return -1;
160 }
161 grp_data.tids[i] = tids[i];
162 }
163
164 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
165 if (!ret) {
166 RME_LOGI("add rtg grp success");
167 }
168 close(fd);
169 return ret;
170 };
171
RemoveRtgThread(int tid)172 int RemoveRtgThread(int tid)
173 {
174 struct rtg_grp_data grp_data;
175 int ret;
176 int fd = BasicOpenRtgNode();
177 if (fd < 0) {
178 return fd;
179 }
180 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
181 grp_data.tid_num = 1;
182 grp_data.tids[0] = tid;
183 grp_data.rtg_cmd = CMD_REMOVE_RTG_THREAD;
184 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
185 if (ret < 0) {
186 RME_LOGE("remove grp failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
187 } else {
188 RME_LOGI("remove grp success, get rtg id %{public}d.", ret);
189 }
190 close(fd);
191 return ret;
192 };
193
ClearRtgGrp(int GrpId)194 int ClearRtgGrp(int GrpId)
195 {
196 struct rtg_grp_data grp_data;
197 int ret;
198 int fd = BasicOpenRtgNode();
199 if (fd < 0) {
200 return fd;
201 }
202 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
203 grp_data.rtg_cmd = CMD_CLEAR_RTG_GRP;
204 grp_data.grp_id = GrpId;
205 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
206 if (ret < 0) {
207 RME_LOGE("clear rtg grp failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
208 } else {
209 RME_LOGI("clear rtg grp success, get rtg id %{public}d.", ret);
210 }
211 close(fd);
212 return ret;
213 };
214
DestroyRtgGrp(int GrpId)215 int DestroyRtgGrp(int GrpId)
216 {
217 struct rtg_grp_data grp_data;
218 int ret;
219 int fd = BasicOpenRtgNode();
220 if (fd < 0) {
221 return fd;
222 }
223 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
224 grp_data.rtg_cmd = CMD_DESTROY_RTG_GRP;
225 grp_data.grp_id = GrpId;
226 ret = ioctl(fd, CMD_ID_SET_RTG, &grp_data);
227 if (ret < 0) {
228 RME_LOGE("destroy rtg grp failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
229 } else {
230 RME_LOGI("destroy rtg grp success, get rtg id:%{public}d, ret:%{public}d.", GrpId, ret);
231 }
232 close(fd);
233 return ret;
234 };
235
236
SetMaxVipRtgs(int rtframe)237 int SetMaxVipRtgs(int rtframe)
238 {
239 int ret = 0;
240 char str_data[MAX_STR_LEN] = {};
241 (void)sprintf_s(str_data, sizeof(str_data), "rtframe:%d", rtframe);
242 struct rtg_str_data strData;
243 strData.len = strlen(str_data);
244 strData.data = str_data;
245
246 int fd = BasicOpenRtgNode();
247 if (fd < 0) {
248 return fd;
249 }
250 ret = ioctl(fd, CMD_ID_SET_CONFIG, &strData);
251 if (ret < 0) {
252 RME_LOGE("set single config failed, ret = %{public}d", ret);
253 } else {
254 RME_LOGI("set single config success, get rtg id %{public}d.", ret);
255 }
256 close(fd);
257 return ret;
258 }
259
SetFrameRateAndPrioType(int rtgId,int rate,int rtgType)260 int SetFrameRateAndPrioType(int rtgId, int rate, int rtgType)
261 {
262 int ret = 0;
263 char str_data[MAX_LENGTH] = {};
264 (void)sprintf_s(str_data, sizeof(str_data), "rtgId:%d;rate:%d;type:%d", rtgId, rate, rtgType);
265 struct rtg_str_data strData;
266 strData.len = strlen(str_data);
267 strData.data = str_data;
268
269 int fd = BasicOpenRtgNode();
270 if (fd < 0) {
271 return fd;
272 }
273 ret = ioctl(fd, CMD_ID_SET_RTG_ATTR, &strData);
274 if (ret < 0) {
275 RME_LOGE("set rtg attr failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
276 } else {
277 RME_LOGI("set rtg attr success, get rtg id %{public}d.", ret);
278 }
279 close(fd);
280 return ret;
281 }
282
BeginFrameFreq(int grpId,int stateParam)283 int BeginFrameFreq(int grpId, int stateParam)
284 {
285 int ret = 0;
286 struct proc_state_data state_data;
287 state_data.grp_id = grpId;
288 state_data.state_param = stateParam;
289
290 int fd = BasicOpenRtgNode();
291 if (fd < 0) {
292 return fd;
293 }
294 ret = ioctl(fd, CMD_ID_BEGIN_FRAME_FREQ, &state_data);
295 close(fd);
296 return ret;
297 }
298
EndFrameFreq(int grpId)299 int EndFrameFreq(int grpId)
300 {
301 int ret = 0;
302 struct proc_state_data state_data;
303 state_data.grp_id = grpId;
304 state_data.state_param = 0;
305
306 int fd = BasicOpenRtgNode();
307 if (fd < 0) {
308 return fd;
309 }
310 ret = ioctl(fd, CMD_ID_END_FRAME_FREQ, &state_data);
311 close(fd);
312 return ret;
313 }
314
EndScene(int grpId)315 int EndScene(int grpId)
316 {
317 int ret = 0;
318 struct proc_state_data state_data;
319 state_data.grp_id = grpId;
320
321 int fd = BasicOpenRtgNode();
322 if (fd < 0) {
323 return fd;
324 }
325 ret = ioctl(fd, CMD_ID_END_SCENE, &state_data);
326 if (ret >= 0) {
327 RME_LOGI("set EndScene success, get ret %{public}d.", ret);
328 }
329 close(fd);
330
331 return ret;
332 }
333
SetMinUtil(int grpId,int stateParam)334 int SetMinUtil(int grpId, int stateParam)
335 {
336 int ret = 0;
337 struct proc_state_data state_data;
338 state_data.grp_id = grpId;
339 state_data.state_param = stateParam;
340
341 int fd = BasicOpenRtgNode();
342 if (fd < 0) {
343 return fd;
344 }
345 ret = ioctl(fd, CMD_ID_SET_MIN_UTIL, &state_data);
346 if (ret < 0) {
347 RME_LOGE("set min util failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
348 } else {
349 RME_LOGI("set min util success, get ret %{public}d.", ret);
350 }
351 close(fd);
352 return ret;
353 }
354
SetMargin(int grpId,int stateParam)355 int SetMargin(int grpId, int stateParam)
356 {
357 int ret = 0;
358 struct proc_state_data state_data;
359 state_data.grp_id = grpId;
360 state_data.state_param = stateParam;
361
362 int fd = BasicOpenRtgNode();
363 if (fd < 0) {
364 return fd;
365 }
366 ret = ioctl(fd, CMD_ID_SET_MARGIN, &state_data);
367 close(fd);
368 return ret;
369 }
370
ListRtgGroup(vector<int> * rs)371 int ListRtgGroup(vector<int> *rs)
372 {
373 int ret = 0;
374 struct rtg_info rtg_info;
375 int fd = BasicOpenRtgNode();
376 if (fd < 0) {
377 return fd;
378 }
379 if (!rs) {
380 return -1;
381 }
382 (void)memset_s(&rtg_info, sizeof(struct rtg_info), 0, sizeof(struct rtg_info));
383 ret = ioctl(fd, CMD_ID_LIST_RTG, &rtg_info);
384 if (ret < 0) {
385 RME_LOGE("list rtg group failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
386 } else {
387 RME_LOGI("list rtg group success with num %{public}d", rtg_info.rtg_num);
388 rs->clear();
389 for (int i = 0; i < rtg_info.rtg_num; i++) {
390 rs->push_back(rtg_info.rtgs[i]);
391 }
392 }
393 close(fd);
394 return ret;
395 }
396
ListRtgThread(int grpId,vector<int> * rs)397 int ListRtgThread(int grpId, vector<int> *rs)
398 {
399 int ret = 0;
400 struct rtg_grp_data grp_data;
401 int fd = BasicOpenRtgNode();
402 if (fd < 0) {
403 return fd;
404 }
405 if (!rs) {
406 return -1;
407 }
408 (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
409 grp_data.grp_id = grpId;
410 ret = ioctl(fd, CMD_ID_LIST_RTG_THREAD, &grp_data);
411 if (ret < 0) {
412 RME_LOGE("list rtg thread failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
413 } else {
414 RME_LOGI("list rtg thread success with tid num %{public}d", grp_data.tid_num);
415 rs->clear();
416 for (int i = 0; i < grp_data.tid_num; i++) {
417 rs->push_back(grp_data.tids[i]);
418 }
419 }
420 close(fd);
421 return ret;
422 }
423
SearchRtgForTid(int tid)424 int SearchRtgForTid(int tid)
425 {
426 int ret = 0;
427 struct proc_state_data search_data;
428 int fd = BasicOpenRtgNode();
429 if (fd < 0) {
430 return fd;
431 }
432 if (tid <= 0) {
433 RME_LOGI("Search tid err: invalid tid.");
434 return -1;
435 }
436 (void)memset_s(&search_data, sizeof(struct proc_state_data), 0, sizeof(struct proc_state_data));
437 search_data.state_param = tid;
438 ret = ioctl(fd, CMD_ID_SEARCH_RTG, &search_data);
439 if (ret > 0) {
440 RME_LOGD("Search tid %{public}d success with rtg_grp %{public}d", tid, ret);
441 }
442 close(fd);
443 return ret;
444 }
445
GetRtgEnable()446 int GetRtgEnable()
447 {
448 struct rtg_enable_data enableData;
449 int fd = BasicOpenRtgNode();
450 if (fd < 0) {
451 return fd;
452 }
453 return ioctl(fd, CMD_ID_GET_ENABLE, &enableData);
454 }
455 } // namespace RME
456 } // namespace OHOS
457