• 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 <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