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