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