1
2 /*
3 * Copyright (c) 2024 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "qos.h"
17 #include "inner_api/qos.h"
18 #include "concurrent_task_log.h"
19 #include <unistd.h>
20 #include <string>
21 #include <mutex>
22 #include <unordered_map>
23 #include <dlfcn.h>
24
25 static constexpr int ERROR_NUM = -1;
26
27 const char* GEWU_CLIENT_LIB = "libgewu_client.z.so";
28
29 const char* GEWU_CREATE_SESSION_FUNC = "GewuCreateSession";
30 const char* GEWU_DESTROY_SESSION_FUNC = "GewuDestroySession";
31 const char* GEWU_SUBMIT_REQUEST_FUNC = "GewuSubmitRequest";
32 const char* GEWU_ABORT_REQUEST_FUNC = "GewuAbortRequest";
33
34 using namespace OHOS::QOS;
35 using namespace std;
36
OH_QoS_SetThreadQoS(QoS_Level level)37 int OH_QoS_SetThreadQoS(QoS_Level level)
38 {
39 if (level < QOS_BACKGROUND || level > QOS_USER_INTERACTIVE) {
40 return ERROR_NUM;
41 }
42 return SetThreadQos(static_cast<QosLevel>(level));
43 }
44
OH_QoS_ResetThreadQoS(void)45 int OH_QoS_ResetThreadQoS(void)
46 {
47 return ResetThreadQos();
48 }
49
OH_QoS_GetThreadQoS(QoS_Level * level)50 int OH_QoS_GetThreadQoS(QoS_Level *level)
51 {
52 if (level == nullptr) {
53 return ERROR_NUM;
54 }
55 QosLevel qosLevel;
56 int ret = GetThreadQos(qosLevel);
57 if (ret < 0) {
58 return ERROR_NUM;
59 }
60 if (static_cast<int>(qosLevel) < QoS_Level::QOS_BACKGROUND ||
61 static_cast<int>(qosLevel) > QoS_Level::QOS_USER_INTERACTIVE) {
62 return ERROR_NUM;
63 }
64 *level = static_cast<QoS_Level>(qosLevel);
65 return 0;
66 }
67
68 using GewuCreateSessionFunc = OH_QoS_GewuCreateSessionResult(*)(const char* attributes);
69 using GewuDestroySessionFunc = OH_QoS_GewuErrorCode(*)(OH_QoS_GewuSession session);
70 using GewuAbortRequestFunc = OH_QoS_GewuErrorCode(*)(OH_QoS_GewuSession session, OH_QoS_GewuRequest request);
71 using GewuSubmitRequestFunc = OH_QoS_GewuSubmitRequestResult(*)(OH_QoS_GewuSession session, const char* request,
72 OH_QoS_GewuOnResponse callback, void *context);
73
74 std::once_flag g_gewuInitFlag;
75 bool g_gewuInitialized = false;
76
77 void* g_gewuNdkLibHandler = nullptr;
78
79 GewuCreateSessionFunc g_CreateSession = nullptr;
80 GewuDestroySessionFunc g_DestroySession = nullptr;
81 GewuSubmitRequestFunc g_SubmitRequest = nullptr;
82 GewuAbortRequestFunc g_AbortRequest = nullptr;
83
LoadSymbol(const char * symbolName)84 static inline void *LoadSymbol(const char* symbolName)
85 {
86 void* funcPtr = dlsym(g_gewuNdkLibHandler, symbolName);
87 if (funcPtr == nullptr) {
88 CONCUR_LOGE("[Gewu] failed to load symbol: %{public}s, error: %{public}s", symbolName, dlerror());
89 }
90 return funcPtr;
91 }
92
LoadSymbols(void)93 static int LoadSymbols(void)
94 {
95 g_CreateSession = reinterpret_cast<GewuCreateSessionFunc>(LoadSymbol(GEWU_CREATE_SESSION_FUNC));
96 if (g_CreateSession == nullptr) {
97 return -1;
98 }
99
100 g_DestroySession = reinterpret_cast<GewuDestroySessionFunc>(LoadSymbol(GEWU_DESTROY_SESSION_FUNC));
101 if (g_DestroySession == nullptr) {
102 return -1;
103 }
104
105 g_SubmitRequest = reinterpret_cast<GewuSubmitRequestFunc>(LoadSymbol(GEWU_SUBMIT_REQUEST_FUNC));
106 if (g_SubmitRequest == nullptr) {
107 return -1;
108 }
109
110 g_AbortRequest = reinterpret_cast<GewuAbortRequestFunc>(LoadSymbol(GEWU_ABORT_REQUEST_FUNC));
111 if (g_AbortRequest == nullptr) {
112 return -1;
113 }
114
115 return 0;
116 }
117
InitializeGewu(void)118 __attribute__((noinline)) static void InitializeGewu(void)
119 {
120 g_gewuNdkLibHandler = dlopen(GEWU_CLIENT_LIB, RTLD_LAZY | RTLD_LOCAL);
121 if (g_gewuNdkLibHandler == nullptr) {
122 CONCUR_LOGE("[Gewu] failed to load library: %{public}s, error: %{public}s", GEWU_CLIENT_LIB, dlerror());
123 return;
124 }
125 int err = LoadSymbols();
126 if (err != 0) {
127 dlclose(g_gewuNdkLibHandler);
128 g_gewuNdkLibHandler = nullptr;
129 return;
130 }
131 g_gewuInitialized = true;
132 }
133
EnsureGewuInitialized(void)134 static inline bool EnsureGewuInitialized(void)
135 {
136 std::call_once(g_gewuInitFlag, InitializeGewu);
137 return g_gewuInitialized;
138 }
139
OH_QoS_GewuCreateSession(const char * attributes)140 extern "C" OH_QoS_GewuCreateSessionResult OH_QoS_GewuCreateSession(const char* attributes)
141 {
142 if (!EnsureGewuInitialized()) {
143 return {OH_QOS_GEWU_INVALID_SESSION_ID, OH_QOS_GEWU_NOSYS};
144 }
145 return g_CreateSession(attributes);
146 }
147
OH_QoS_GewuDestroySession(OH_QoS_GewuSession session)148 extern "C" OH_QoS_GewuErrorCode OH_QoS_GewuDestroySession(OH_QoS_GewuSession session)
149 {
150 if (!EnsureGewuInitialized()) {
151 return OH_QOS_GEWU_NOSYS;
152 }
153 return g_DestroySession(session);
154 }
155
OH_QoS_GewuSubmitRequest(OH_QoS_GewuSession session,const char * request,OH_QoS_GewuOnResponse callback,void * context)156 extern "C" OH_QoS_GewuSubmitRequestResult OH_QoS_GewuSubmitRequest(OH_QoS_GewuSession session, const char* request,
157 OH_QoS_GewuOnResponse callback, void* context)
158 {
159 if (!EnsureGewuInitialized()) {
160 return {OH_QOS_GEWU_INVALID_REQUEST_ID, OH_QOS_GEWU_NOSYS};
161 }
162 return g_SubmitRequest(session, request, callback, context);
163 }
164
OH_QoS_GewuAbortRequest(OH_QoS_GewuSession session,OH_QoS_GewuRequest request)165 extern "C" OH_QoS_GewuErrorCode OH_QoS_GewuAbortRequest(OH_QoS_GewuSession session, OH_QoS_GewuRequest request)
166 {
167 if (!EnsureGewuInitialized()) {
168 return OH_QOS_GEWU_NOSYS;
169 }
170 return g_AbortRequest(session, request);
171 }
172