• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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