1 /*
2 * Copyright (c) 2023 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 License at
6 *
7 *     http://www.apache.org/license/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 
17 #ifndef __FFRT_TASKCLIENT_ADAPTER_H__
18 #define __FFRT_TASKCLIENT_ADAPTER_H__
19 
20 #include <atomic>
21 #include <chrono>
22 #include <dlfcn.h>
23 #include "internal_inc/osal.h"
24 #include "dfx/log/ffrt_log_api.h"
25 
26 
27 #if (defined(QOS_WORKER_FRAME_RTG) || defined(QOS_FRAME_RTG))
28 
29 struct IntervalReply {
30     int rtgId;
31     int tid;
32     int paramA;
33     int paramB;
34     std::string bundleName;
35 };
36 
37 enum QueryIntervalItem {
38     QUERY_UI = 0,
39     QUERY_RENDER = 1,
40     QUERY_RENDER_SERVICE = 2,
41     QUERY_COMPOSER = 3,
42     QUERY_HARDWARE = 4,
43     QUERY_EXECUTOR_START = 5,
44     QUERY_TYPE_MAX
45 };
46 
47 extern "C" {
48     int AddThreadToRtg(int tid, int grpId, int prioType = 0);
49     int DestroyRtgGrp(int grpId);
50     int BeginFrameFreq(int stateParam);
51     int EndFrameFreq(int stateParam);
52     void CTC_QueryInterval(int queryItem, IntervalReply& queryRs);
53 }
54 
55 static const std::string TRACE_LIB_PATH_1 = "/system/lib64/libconcurrentsvc.z.so";
56 static const std::string TRACE_LIB_PATH_2 = "/system/lib64/libconcurrent_task_client.z.so";
57 
58 class TaskClientAdapter {
59 public:
TaskClientAdapter()60     TaskClientAdapter()
61     {
62         Load();
63     }
64 
~TaskClientAdapter()65     ~TaskClientAdapter()
66     {
67         UnLoad();
68     }
69 
Instance()70     static TaskClientAdapter* Instance()
71     {
72         static TaskClientAdapter instance;
73         return &instance;
74     }
75 
76 #define REG_FUNC(func) using func##Type = decltype(func)*; func##Type func##Func = nullptr
77     REG_FUNC(AddThreadToRtg);
78     REG_FUNC(BeginFrameFreq);
79     REG_FUNC(EndFrameFreq);
80     REG_FUNC(DestroyRtgGrp);
81     REG_FUNC(CTC_QueryInterval);
82 #undef REG_FUNC
83 
84 private:
Load()85     void Load()
86     {
87         if (handle_1 != nullptr) {
88             FFRT_LOGD("handle_1 exits");
89             return;
90         }
91         if (handle_2 != nullptr) {
92             FFRT_LOGD("handle_2 exits");
93             return;
94         }
95 
96         handle_1 = dlopen(TRACE_LIB_PATH_1.c_str(), RTLD_NOW | RTLD_LOCAL);
97         if (handle_1 == nullptr) {
98             FFRT_LOGE("load so[%s] fail", TRACE_LIB_PATH_1.c_str());
99             return;
100         }
101 
102         handle_2 = dlopen(TRACE_LIB_PATH_2.c_str(), RTLD_NOW | RTLD_LOCAL);
103         if (handle_2 == nullptr) {
104             FFRT_LOGE("load so[%s] fail", TRACE_LIB_PATH_2.c_str());
105             return;
106         }
107 
108 #define LOAD_FUNC(func) func##Func = reinterpret_cast<func##Type>(dlsym(handle_1, #func));      \
109         if (func##Func != nullptr) {                                                            \
110             FFRT_LOGI("load func %s from %s success", #func, TRACE_LIB_PATH_1.c_str());         \
111         } else {                                                                                \
112             func##Func = reinterpret_cast<func##Type>(dlsym(handle_2, #func));                  \
113             if (func##Func == nullptr) {                                                        \
114                 FFRT_LOGE("load func %s from %s failed", #func, TRACE_LIB_PATH_2.c_str());      \
115             }                                                                                   \
116         }
117 
118             LOAD_FUNC(AddThreadToRtg);
119             LOAD_FUNC(BeginFrameFreq);
120             LOAD_FUNC(EndFrameFreq);
121             LOAD_FUNC(DestroyRtgGrp);
122             LOAD_FUNC(CTC_QueryInterval);
123 #undef LOAD_FUNC
124     }
125 
UnLoad()126     void UnLoad()
127     {
128         if (handle_1 != nullptr) {
129             if (dlclose(handle_1) != 0) {
130                 FFRT_LOGE("unLoad handle_1 fail");
131             }
132             handle_1 = nullptr;
133         }
134         if (handle_2 != nullptr) {
135             if (dlclose(handle_2) != 0) {
136                 FFRT_LOGE("unLoad handle_2 fail");
137             }
138             handle_2 = nullptr;
139         }
140     }
141 
142     void* handle_1 = nullptr;
143     void* handle_2 = nullptr;
144 };
145 
EndFrameFreqAdapter(int stateParam)146 static int EndFrameFreqAdapter(int stateParam)
147 {
148     auto func = TaskClientAdapter::Instance()->EndFrameFreqFunc;
149     if (func != nullptr) {
150         return func(stateParam);
151     }
152     return -1;
153 }
154 
BeginFrameFreqAdapter(int stateParam)155 static int BeginFrameFreqAdapter(int stateParam)
156 {
157     auto func = TaskClientAdapter::Instance()->BeginFrameFreqFunc;
158     if (func != nullptr) {
159         return func(stateParam);
160     }
161     return -1;
162 }
163 
DestroyRtgGrpAdapter(int grpId)164 static int DestroyRtgGrpAdapter(int grpId)
165 {
166     auto func = TaskClientAdapter::Instance()->DestroyRtgGrpFunc;
167     if (func != nullptr) {
168         return func(grpId);
169     }
170     return -1;
171 }
172 
173 static int AddThreadToRtgAdapter(int tid, int grpId, int prioType = 0)
174 {
175     auto func = TaskClientAdapter::Instance()->AddThreadToRtgFunc;
176     if (func != nullptr) {
177         return func(tid, grpId, prioType);
178     }
179     return -1;
180 }
181 
182 #define CTC_QUERY_INTERVAL(queryItem, queryRs)                             \
183     do {                                                                   \
184         auto func = TaskClientAdapter::Instance()->CTC_QueryIntervalFunc;   \
185         if (func != nullptr) {                                             \
186             func(queryItem, queryRs);                                      \
187         }                                                                  \
188     } while (0)
189 
190 #endif /* __FFRT_TASKCLIENT_ADAPTER_H__ */
191 #endif /* QOS_FRAME_RTG */
192