• 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 #undef LOG_TAG
29 #define LOG_TAG "rtg_interface"
30 
31 namespace OHOS {
32 namespace RME {
33 namespace {
34 constexpr size_t MAX_LENGTH = 100;
35 }
36 
37 const char RTG_SCHED_IPC_MAGIC = 0xAB;
38 static int g_fd = -1;
39 
40 #define CMD_ID_SET_ENABLE \
41     _IOWR(RTG_SCHED_IPC_MAGIC, SET_ENABLE, struct rtg_enable_data)
42 #define CMD_ID_SET_RTG \
43     _IOWR(RTG_SCHED_IPC_MAGIC, SET_RTG, struct rtg_str_data)
44 #define CMD_ID_SET_CONFIG \
45     _IOWR(RTG_SCHED_IPC_MAGIC, SET_CONFIG, struct rtg_str_data)
46 #define CMD_ID_SET_RTG_ATTR \
47     _IOWR(RTG_SCHED_IPC_MAGIC, SET_RTG_ATTR, struct rtg_str_data)
48 #define CMD_ID_BEGIN_FRAME_FREQ \
49     _IOWR(RTG_SCHED_IPC_MAGIC, BEGIN_FRAME_FREQ, struct proc_state_data)
50 #define CMD_ID_END_FRAME_FREQ \
51     _IOWR(RTG_SCHED_IPC_MAGIC, END_FRAME_FREQ, struct proc_state_data)
52 #define CMD_ID_END_SCENE \
53     _IOWR(RTG_SCHED_IPC_MAGIC, END_SCENE, struct proc_state_data)
54 #define CMD_ID_SET_MIN_UTIL \
55     _IOWR(RTG_SCHED_IPC_MAGIC, SET_MIN_UTIL, struct proc_state_data)
56 #define CMD_ID_SET_MAX_UTIL \
57     _IOWR(RTG_SCHED_IPC_MAGIC, SET_MAX_UTIL, struct proc_state_data)
58 #define CMD_ID_SET_MARGIN \
59     _IOWR(RTG_SCHED_IPC_MAGIC, SET_MARGIN, struct proc_state_data)
60 #define CMD_ID_SEARCH_RTG \
61     _IOWR(RTG_SCHED_IPC_MAGIC, SEARCH_RTG, struct proc_state_data)
62 #define CMD_ID_GET_ENABLE \
63     _IOWR(RTG_SCHED_IPC_MAGIC, GET_ENABLE, struct rtg_enable_data)
64 
BasicOpenRtgNode()65 __attribute__((constructor)) void BasicOpenRtgNode()
66 {
67     char fileName[] = "/proc/self/sched_rtg_ctrl";
68     FILE* fd = fopen(fileName, "r+");
69     if (fd == nullptr) {
70         RME_LOGI("rtg Open fail, errno = %{public}d(%{public}s), dev = %{public}s", errno, strerror(errno), fileName);
71         return;
72     }
73     g_fd = fileno(fd);
74     if (g_fd < 0) {
75         return;
76     }
77     RME_LOGI("rtg Open success");
78     return;
79 }
80 
BasicCloseRtgNode()81 __attribute__((destructor)) void BasicCloseRtgNode()
82 {
83     if (g_fd < 0) {
84         return;
85     }
86     FILE* fd = fdopen(g_fd, "r+");
87     if (fd != nullptr) {
88         RME_LOGI("rtg Close g_fd ret is %{public}d", g_fd);
89         fclose(fd);
90     }
91     g_fd = -1;
92 }
93 
EnableRtg(bool flag)94 int EnableRtg(bool flag)
95 {
96     int ret = 0;
97     struct rtg_enable_data enableData;
98     char configStr[] = "load_freq_switch:1;sched_cycle:1";
99     enableData.enable = flag;
100     enableData.len = sizeof(configStr);
101     enableData.data = configStr;
102     if (g_fd < 0) {
103         return g_fd;
104     }
105     ret = ioctl(g_fd, CMD_ID_SET_ENABLE, &enableData);
106     if (ret != 0) {
107         RME_LOGE("set rtg config to [%{public}d] failed, ret = %{public}d, errno = %{public}d (%{public}s)",
108             flag,
109             ret,
110             errno,
111             strerror(errno));
112     } else {
113         RME_LOGI("set rtg config to [%{public}d] success.", flag);
114     }
115     return 0;
116 };
117 
AddThreadToRtg(int tid,int grpId,int prioType,bool isBlue)118 int AddThreadToRtg(int tid, int grpId, int prioType, [[maybe_unused]] bool isBlue)
119 {
120     if (g_fd < 0) {
121         return g_fd;
122     }
123     struct rtg_grp_data grp_data;
124     int ret;
125     (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
126     grp_data.tid_num = 1;
127     grp_data.tids[0] = tid;
128     grp_data.grp_id = grpId;
129     grp_data.rtg_cmd = CMD_ADD_RTG_THREAD;
130     grp_data.prio_type = prioType;
131     ret = ioctl(g_fd, CMD_ID_SET_RTG, &grp_data);
132     if (ret != 0) {
133         RME_LOGE("add thread to rtg failed, grpId = %{public}d, ret = %{public}d, errno = %{public}d (%{public}s)",
134             grpId,
135             ret,
136             errno,
137             strerror(errno));
138     } else {
139         RME_LOGI("add thread to rtg success");
140     }
141     return ret;
142 }
143 
AddThreadsToRtg(vector<int> tids,int grpId,int prioType,bool isBlue)144 int AddThreadsToRtg(vector<int> tids, int grpId, int prioType, [[maybe_unused]] bool isBlue)
145 {
146     struct rtg_grp_data grp_data;
147     int ret;
148     if (g_fd < 0) {
149         return g_fd;
150     }
151     (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
152     int num = static_cast<int>(tids.size());
153     if (num > MAX_TID_NUM) {
154         return -1;
155     }
156     grp_data.tid_num = num;
157     grp_data.grp_id = grpId;
158     grp_data.rtg_cmd = CMD_ADD_RTG_THREAD;
159     grp_data.prio_type = prioType;
160     for (int i = 0; i < num; i++) {
161         if (tids[i] < 0) {
162             return -1;
163         }
164         grp_data.tids[i] = tids[i];
165     }
166     ret = ioctl(g_fd, CMD_ID_SET_RTG, &grp_data);
167     if (ret == 0) {
168         RME_LOGI("add rtg grp success");
169     } else {
170         RME_LOGE("add thread to rtg failed, grpId = %{public}d, ret = %{public}d, errno = %{public}d (%{public}s)",
171             grpId,
172             ret,
173             errno,
174             strerror(errno));
175     }
176     return ret;
177 };
178 
RemoveRtgThread(int tid,bool isBlue)179 int RemoveRtgThread(int tid, [[maybe_unused]] bool isBlue)
180 {
181     if (g_fd < 0) {
182         return g_fd;
183     }
184     struct rtg_grp_data grp_data;
185     int ret;
186     (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
187     grp_data.tid_num = 1;
188     grp_data.tids[0] = tid;
189     grp_data.rtg_cmd = CMD_REMOVE_RTG_THREAD;
190     ret = ioctl(g_fd, CMD_ID_SET_RTG, &grp_data);
191     if (ret != 0) {
192         RME_LOGE("remove grp failed, ret = %{public}d, errno = %{public}d (%{public}s)", ret, errno, strerror(errno));
193     } else {
194         RME_LOGI("remove grp success.");
195     }
196     return ret;
197 };
198 
RemoveRtgThreads(vector<int> tids,bool isBlue)199 int RemoveRtgThreads(vector<int> tids, [[maybe_unused]] bool isBlue)
200 {
201     struct rtg_grp_data grp_data;
202     int ret;
203     if (g_fd < 0) {
204         return g_fd;
205     }
206     (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
207     int num = static_cast<int>(tids.size());
208     if (num > MAX_TID_NUM) {
209         return -1;
210     }
211     grp_data.tid_num = num;
212     grp_data.rtg_cmd = CMD_REMOVE_RTG_THREAD;
213     for (int i = 0; i < num; i++) {
214         if (tids[i] < 0) {
215             return -1;
216         }
217         grp_data.tids[i] = tids[i];
218     }
219     ret = ioctl(g_fd, CMD_ID_SET_RTG, &grp_data);
220     if (ret < 0) {
221         RME_LOGE("remove grp threads failed, errno = %{public}d (%{public}s)", errno, strerror(errno));
222     } else {
223         RME_LOGI("remove grp threads success, get rtg id %{public}d.", ret);
224     }
225     return ret;
226 }
227 
DestroyRtgGrp(int grpId)228 int DestroyRtgGrp(int grpId)
229 {
230     if (g_fd < 0) {
231         return g_fd;
232     }
233     struct rtg_grp_data grp_data;
234     int ret;
235     (void)memset_s(&grp_data, sizeof(struct rtg_grp_data), 0, sizeof(struct rtg_grp_data));
236     grp_data.rtg_cmd = CMD_DESTROY_RTG_GRP;
237     grp_data.grp_id = grpId;
238     ret = ioctl(g_fd, CMD_ID_SET_RTG, &grp_data);
239     if (ret != 0) {
240         RME_LOGE("destroy rtg grp failed, grpId = %{public}d, ret = %{public}d, errno = %{public}d (%{public}s)",
241             grpId,
242             ret,
243             errno,
244             strerror(errno));
245     } else {
246         RME_LOGI("destroy rtg grp success, get rtg id:%{public}d, ret:%{public}d.", grpId, ret);
247     }
248     return ret;
249 };
250 
SetFrameRateAndPrioType(int rtgId,int rate,int rtgType)251 int SetFrameRateAndPrioType(int rtgId, int rate, int rtgType)
252 {
253     if (g_fd < 0) {
254         return g_fd;
255     }
256     int ret = 0;
257     char str_data[MAX_LENGTH] = {};
258     (void)sprintf_s(str_data, sizeof(str_data), "rtgId:%d;rate:%d;type:%d", rtgId, rate, rtgType);
259     struct rtg_str_data strData;
260     strData.len = strlen(str_data);
261     strData.data = str_data;
262 
263     ret = ioctl(g_fd, CMD_ID_SET_RTG_ATTR, &strData);
264     if (ret != 0) {
265         RME_LOGE("set rtg attr failed (rtgId:%{public}d;rate:%{public}d;type:%{public}d), ret = %{public}d, errno = "
266                  "%{public}d (%{public}s)",
267             rtgId,
268             rate,
269             rtgType,
270             ret,
271             errno,
272             strerror(errno));
273     } else {
274         RME_LOGD("set rtg attr success.");
275     }
276     return ret;
277 }
278 
BeginFrameFreq(int stateParam)279 int BeginFrameFreq(int stateParam)
280 {
281     if (g_fd < 0) {
282         return g_fd;
283     }
284     int ret = 0;
285     struct proc_state_data state_data;
286     state_data.state_param = stateParam;
287 
288     ret = ioctl(g_fd, CMD_ID_BEGIN_FRAME_FREQ, &state_data);
289     return ret;
290 }
291 
EndFrameFreq(int stateParam)292 int EndFrameFreq(int stateParam)
293 {
294     if (g_fd < 0) {
295         return g_fd;
296     }
297     int ret = 0;
298     struct proc_state_data state_data;
299     state_data.state_param = stateParam;
300 
301     ret = ioctl(g_fd, CMD_ID_END_FRAME_FREQ, &state_data);
302     return ret;
303 }
304 
EndScene(int grpId)305 int EndScene(int grpId)
306 {
307     int ret = 0;
308     if (g_fd < 0) {
309         RME_LOGE("Open fail /proc/self/sched_rtg_ctrl");
310         return g_fd;
311     }
312     struct proc_state_data state_data;
313     state_data.grp_id = grpId;
314 
315     ret = ioctl(g_fd, CMD_ID_END_SCENE, &state_data);
316     if (ret == 0) {
317         RME_LOGI("set EndScene success.");
318     }
319     return ret;
320 }
321 
SetMinUtil(int stateParam)322 int SetMinUtil(int stateParam)
323 {
324     int ret = 0;
325     struct proc_state_data state_data;
326     state_data.state_param = stateParam;
327 
328     if (g_fd < 0) {
329         return g_fd;
330     }
331     ret = ioctl(g_fd, CMD_ID_SET_MIN_UTIL, &state_data);
332     if (ret != 0) {
333         RME_LOGE("set min util failed, ret = %{public}d, errno = %{public}d (%{public}s)", ret, errno, strerror(errno));
334     } else {
335         RME_LOGI("set min util success, get ret %{public}d.", ret);
336     }
337     return ret;
338 }
339 
SetMaxUtil(int grpId,int stateParam)340 int SetMaxUtil(int grpId, int stateParam)
341 {
342     return 0;
343 }
344 
SetMargin(int stateParam)345 int SetMargin(int stateParam)
346 {
347     int ret = 0;
348     struct proc_state_data state_data;
349     state_data.state_param = stateParam;
350 
351     if (g_fd < 0) {
352         return g_fd;
353     }
354     ret = ioctl(g_fd, CMD_ID_SET_MARGIN, &state_data);
355     return ret;
356 }
357 
SearchRtgForTid(int tid)358 int SearchRtgForTid(int tid)
359 {
360     if (g_fd < 0) {
361         return g_fd;
362     }
363     if (tid <= 0) {
364         RME_LOGI("Search tid err: invalid tid.");
365         return -1;
366     }
367     int ret = 0;
368     struct proc_state_data search_data;
369     (void)memset_s(&search_data, sizeof(struct proc_state_data), 0, sizeof(struct proc_state_data));
370     search_data.state_param = tid;
371     ret = ioctl(g_fd, CMD_ID_SEARCH_RTG, &search_data);
372     if (ret >= 0) {
373         RME_LOGD("Search tid %{public}d success with rtg_grp %{public}d", tid, ret);
374     }
375     return ret;
376 }
377 
GetRtgEnable()378 int GetRtgEnable()
379 {
380     if (g_fd < 0) {
381         return g_fd;
382     }
383     int ret = 0;
384     struct rtg_enable_data enableData;
385     ret = ioctl(g_fd, CMD_ID_GET_ENABLE, &enableData);
386     if (ret < 0) {
387         RME_LOGE(
388             "get rtg enable failed, ret = %{public}d, errno = %{public}d (%{public}s)", ret, errno, strerror(errno));
389     }
390     return ret;
391 }
392 
GetAppExpelAbility(const std::string & appBundleName)393 bool GetAppExpelAbility(const std::string &appBundleName)
394 {
395     return false;
396 }
397 }  // namespace RME
398 }  // namespace OHOS
399