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