Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "qs_client.h"
12 :
13 : #include <chrono>
14 : #include <thread>
15 : #include "proto/easycom_message.pb.h"
16 : #include "easy_comm.h"
17 :
18 : #include "bqs_log.h"
19 : #include "ezcom_client.h"
20 : #include "bqs_feature_ctrl.h"
21 :
22 : namespace {
23 : const uint32_t MAX_PAGED_BIND_RELATION = 450U;
24 : const int32_t CONNECT_WAIT_TIME_OUT = 10000; // 10s
25 : const uint32_t MAX_CONNECT_CALL_TIMES = 100U;
26 : const uint32_t TIMEOUT_CONNECT_CALL_TIMES = 10U;
27 : const uint32_t CONNECT_CALL_TIME_INTERVAL = 100U; // 100ms
28 : using MsgHandler = void (*)(int32_t fd, struct EzcomRequest *req);
29 : const uint32_t MAX_PAGED_QUEUE_RELATION = 300U;
30 : const int32_t EZCOMSERVER_NOT_START = -2;
31 : }
32 :
33 : namespace bqs {
34 : std::mutex BqsClient::mutex_;
35 : int32_t BqsClient::clientFd_(-1);
36 : bool BqsClient::initFlag_(false);
37 :
38 1 : BqsClient::BqsClient() {}
39 :
40 1 : BqsClient::~BqsClient()
41 : {
42 1 : BQS_LOG_INFO("BqsClient release");
43 1 : const std::unique_lock<std::mutex> bqsLock(mutex_);
44 1 : if (clientFd_ >= 0) {
45 1 : BQS_LOG_INFO("EzcomClosePipe begin");
46 1 : (void)EzcomClosePipe(clientFd_);
47 1 : clientFd_ = -1;
48 : }
49 1 : }
50 :
51 1 : int32_t BqsClient::Destroy() const
52 : {
53 1 : BQS_LOG_INFO("Destroy begin");
54 1 : int32_t ret = 0;
55 :
56 1 : const std::unique_lock<std::mutex> bqsLock(mutex_);
57 1 : if (clientFd_ >= 0) {
58 1 : BQS_LOG_INFO("EzcomClosePipe begin");
59 1 : ret = EzcomClosePipe(clientFd_);
60 1 : clientFd_ = -1;
61 : }
62 :
63 1 : initFlag_ = false;
64 1 : return ret;
65 1 : }
66 :
67 : /**
68 : * Create instance of BqsClient.
69 : * @return BqsClient*: success, nullptr: error
70 : */
71 24 : BqsClient *BqsClient::GetInstance(const char_t * const serverProcName,
72 : const uint32_t procNameLen, const ExeceptionCallback fn)
73 : {
74 24 : if (serverProcName == nullptr) {
75 1 : BQS_LOG_ERROR("BqsClient make instance failed, server name is null");
76 1 : return nullptr;
77 : }
78 23 : std::string serverProcNameTmp;
79 23 : if (FeatureCtrl::IsAosCore()) {
80 1 : serverProcNameTmp = AOSCORE_PREFIX + serverProcName;
81 : } else {
82 22 : serverProcNameTmp = serverProcName;
83 : }
84 :
85 23 : BQS_LOG_INFO("BqsClient GetInstance begin");
86 : {
87 23 : const std::unique_lock<std::mutex> bqsLock(mutex_);
88 23 : if (!initFlag_) {
89 5 : BQS_LOG_RUN_INFO("BqsClient EzcomCreateClient begin, server name:%s, serverCreateTryTime:%u",
90 : serverProcNameTmp.c_str(), MAX_CONNECT_CALL_TIMES);
91 5 : uint32_t connectTime = 1U;
92 5 : uint32_t serverCreateTryTime = 1U;
93 5 : struct EzcomAttr clientAttr;
94 5 : clientAttr.handler = reinterpret_cast<MsgHandler>(fn);
95 5 : clientAttr.targetName = serverProcNameTmp.c_str();
96 5 : clientAttr.timeout = CONNECT_WAIT_TIME_OUT;
97 5 : clientAttr.mode = EZCOM_CLIENT;
98 : while (true) {
99 203 : clientFd_ = EzcomCreateClient(&clientAttr);
100 203 : if (((clientFd_ == -ENXIO) || (clientFd_ == -EAGAIN)) && (connectTime < MAX_CONNECT_CALL_TIMES)) {
101 0 : connectTime++;
102 0 : std::this_thread::sleep_for(std::chrono::milliseconds(CONNECT_CALL_TIME_INTERVAL));
103 0 : continue;
104 : }
105 :
106 203 : if ((clientFd_ == -ETIMEDOUT) && (connectTime < TIMEOUT_CONNECT_CALL_TIMES)) {
107 0 : connectTime++;
108 0 : continue;
109 : }
110 :
111 203 : if ((clientFd_ == EZCOMSERVER_NOT_START) && (serverCreateTryTime < MAX_CONNECT_CALL_TIMES)) {
112 198 : serverCreateTryTime++;
113 198 : std::this_thread::sleep_for(std::chrono::milliseconds(CONNECT_CALL_TIME_INTERVAL));
114 198 : continue;
115 : }
116 :
117 5 : if (clientFd_ <= 0) {
118 3 : BQS_LOG_ERROR("EzcomTimedConnectServer failed, err:%d, connect times:%u, serverCreateTryTime:%u",
119 : clientFd_, connectTime, serverCreateTryTime);
120 3 : return nullptr;
121 : }
122 2 : break;
123 : }
124 :
125 2 : BQS_LOG_RUN_INFO("BqsClient EzcomCreateClient success, server name:%s, connect times:%u",
126 : serverProcNameTmp.c_str(), connectTime);
127 :
128 2 : initFlag_ = true;
129 : }
130 23 : }
131 :
132 20 : static BqsClient instance;
133 20 : BQS_LOG_INFO("BqsClient GetInstance success");
134 20 : return &instance;
135 23 : }
136 :
137 : /**
138 : * Add bind relation, support batch bind.
139 : * @return Number of bind relation success, record already exists indicate successfully add
140 : */
141 5 : uint32_t BqsClient::BindQueue(const std::vector<BQSBindQueueItem> &bindQueueVec,
142 : std::vector<BQSBindQueueResult> &bindResultVec) const
143 : {
144 5 : BQS_LOG_INFO("BqsClient BindQueue begin, vector size:%zu", bindQueueVec.size());
145 5 : if (bindQueueVec.size() > MAX_PAGED_QUEUE_RELATION) {
146 1 : auto bindQueueIter = bindQueueVec.begin();
147 1 : const auto bindQueEndIter = bindQueueVec.end();
148 1 : uint32_t bindNum = 0U;
149 3 : while (bindQueueIter != bindQueEndIter) {
150 2 : auto tempBindQueEndIter = bindQueueIter + MAX_PAGED_QUEUE_RELATION;
151 2 : if (tempBindQueEndIter > bindQueEndIter) {
152 1 : tempBindQueEndIter = bindQueEndIter;
153 : }
154 2 : std::vector<BQSBindQueueItem> bindQueue(bindQueueIter, tempBindQueEndIter);
155 2 : std::vector<BQSBindQueueResult> bindResult;
156 2 : bindNum += DoBindQueue(bindQueue, bindResult);
157 2 : bindResultVec.insert(bindResultVec.end(), bindResult.begin(), bindResult.end());
158 2 : bindQueueIter = tempBindQueEndIter;
159 2 : }
160 1 : return bindNum;
161 : } else {
162 4 : return DoBindQueue(bindQueueVec, bindResultVec);
163 : }
164 : }
165 :
166 6 : uint32_t BqsClient::DoBindQueue(const std::vector<BQSBindQueueItem> &bindQueueVec,
167 : std::vector<BQSBindQueueResult> &bindResultVec) const
168 : {
169 6 : BQS_LOG_INFO("BqsClient DoBindQueue begin, vector size:%zu", bindQueueVec.size());
170 6 : BQSMsg bqsReqMsg = {};
171 6 : BQSMsg bqsRespMsg = {};
172 6 : if (EzcomClient::GetInstance(clientFd_)->SerializeBindMsg(bindQueueVec, bqsReqMsg) != BQS_STATUS_OK) {
173 2 : return 0U;
174 : }
175 :
176 4 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
177 0 : return 0U;
178 : }
179 4 : return EzcomClient::GetInstance(clientFd_)->ParseBindRespMsg(bqsRespMsg, bindResultVec);
180 6 : }
181 :
182 : /**
183 : * Delete bind relation, support batch unbind according to src queueId or dst queueId or src-dst queueId
184 : * @return Number of unbind relation success, record not exists indicate successfully delete
185 : */
186 4 : uint32_t BqsClient::UnbindQueue(const std::vector<BQSQueryPara> &bqsQueryParaVec,
187 : std::vector<BQSBindQueueResult> &bindResultVec) const
188 : {
189 4 : BQS_LOG_INFO("BqsClient UnbindQueue begin, vector size:%zu", bqsQueryParaVec.size());
190 4 : if (bqsQueryParaVec.size() > MAX_PAGED_QUEUE_RELATION) {
191 1 : auto bindQueueIter = bqsQueryParaVec.begin();
192 1 : const auto bindQueEndIter = bqsQueryParaVec.end();
193 1 : uint32_t bindNum = 0U;
194 3 : while (bindQueueIter != bindQueEndIter) {
195 2 : auto tempBindQueEndIter = bindQueueIter + MAX_PAGED_QUEUE_RELATION;
196 2 : if (tempBindQueEndIter > bindQueEndIter) {
197 1 : tempBindQueEndIter = bindQueEndIter;
198 : }
199 2 : std::vector<BQSQueryPara> bindQueue(bindQueueIter, tempBindQueEndIter);
200 2 : std::vector<BQSBindQueueResult> bindResult;
201 2 : bindNum += DoUnbindQueue(bindQueue, bindResult);
202 2 : bindResultVec.insert(bindResultVec.end(), bindResult.begin(), bindResult.end());
203 2 : bindQueueIter = tempBindQueEndIter;
204 2 : }
205 1 : return bindNum;
206 : } else {
207 3 : return DoUnbindQueue(bqsQueryParaVec, bindResultVec);
208 : }
209 : }
210 :
211 5 : uint32_t BqsClient::DoUnbindQueue(const std::vector<BQSQueryPara> &bqsQueryParaVec,
212 : std::vector<BQSBindQueueResult> &bindResultVec) const
213 : {
214 5 : BQS_LOG_INFO("BqsClient DoUnbindQueue begin, vector size:%zu", bqsQueryParaVec.size());
215 5 : BQSMsg bqsReqMsg = {};
216 5 : BQSMsg bqsRespMsg = {};
217 5 : if (EzcomClient::GetInstance(clientFd_)->SerializeUnbindMsg(bqsQueryParaVec, bqsReqMsg) != BQS_STATUS_OK) {
218 0 : return 0U;
219 : }
220 :
221 5 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
222 2 : return 0U;
223 : }
224 3 : return EzcomClient::GetInstance(clientFd_)->ParseBindRespMsg(bqsRespMsg, bindResultVec);
225 5 : }
226 :
227 : /**
228 : * Get bind relation, support get bind according to src queueId or dst queueId
229 : * @return Number of get bind relation success
230 : */
231 3 : uint32_t BqsClient::GetBindQueue(const BQSQueryPara &queryPara, std::vector<BQSBindQueueItem> &bindQueueVec) const
232 : {
233 3 : BQS_LOG_INFO("BqsClient GetBindQueue begin");
234 3 : BQSMsg bqsReqMsg = {};
235 3 : BQSMsg bqsRespMsg = {};
236 3 : if (EzcomClient::GetInstance(clientFd_)->SerializeGetBindMsg(queryPara, bqsReqMsg) != BQS_STATUS_OK) {
237 0 : return 0U;
238 : }
239 :
240 3 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
241 2 : return 0U;
242 : }
243 1 : return EzcomClient::GetInstance(clientFd_)->ParseGetBindRespMsg(bqsRespMsg, bindQueueVec);
244 3 : }
245 :
246 : /**
247 : * Get paged bind relation
248 : * @return Number of get bind relation success
249 : */
250 3 : uint32_t BqsClient::GetPagedBindQueue(const uint32_t offset, const uint32_t limit,
251 : std::vector<BQSBindQueueItem> &bindQueueVec, uint32_t &total) const
252 : {
253 3 : BQS_LOG_INFO("BqsClient GetPagedBindQueue begin, offset:%u, limit:%u.", offset, limit);
254 3 : BQSMsg bqsReqMsg = {};
255 3 : BQSMsg bqsRespMsg = {};
256 3 : if (EzcomClient::GetInstance(clientFd_)->SerializeGetPagedBindMsg(offset, limit, bqsReqMsg) != BQS_STATUS_OK) {
257 0 : return 0U;
258 : }
259 :
260 3 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
261 1 : return 0U;
262 : }
263 2 : return EzcomClient::GetInstance(clientFd_)->ParseGetPagedBindRespMsg(bqsRespMsg, bindQueueVec, total);
264 3 : }
265 :
266 : /**
267 : * Get all bind relation
268 : * @return Number of get bind relation success
269 : */
270 3 : uint32_t BqsClient::GetAllBindQueue(std::vector<BQSBindQueueItem> &bindQueueVec) const
271 : {
272 3 : BQS_LOG_INFO("BqsClient GetAllBindQueue begin");
273 3 : uint32_t offset = 0U;
274 3 : uint32_t total = 0U;
275 : do {
276 3 : std::vector<BQSBindQueueItem> pagedBindQueueVec;
277 3 : const auto getNum = GetPagedBindQueue(offset, MAX_PAGED_BIND_RELATION, pagedBindQueueVec, total);
278 3 : if (getNum == 0U) {
279 1 : break;
280 : }
281 :
282 4 : for (size_t i = 0U; i < pagedBindQueueVec.size(); i++) {
283 2 : bindQueueVec.emplace_back(pagedBindQueueVec[i]);
284 : }
285 :
286 2 : bool isOverflow = false;
287 2 : BqsCheckAssign32UAdd(offset, getNum, offset, isOverflow);
288 2 : if (isOverflow) {
289 0 : break;
290 : }
291 2 : BQS_LOG_INFO("BqsClient GetPagedBindQueue success, total:%u, getNum:%u, offset:%u", total, getNum, offset);
292 5 : } while (offset < total);
293 :
294 3 : return offset;
295 : }
296 :
297 1 : uint32_t BqsClient::BindQueueMbufPool(const std::vector<BQSBindQueueMbufPoolItem> &bindQueueVec,
298 : std::vector<BQSBindQueueResult> &bindResultVec) const
299 : {
300 : (void)(bindQueueVec);
301 : (void)(bindResultVec);
302 1 : return 0;
303 : }
304 :
305 1 : uint32_t BqsClient::UnbindQueueMbufPool(const std::vector<BQSUnbindQueueMbufPoolItem> &bindQueueVec,
306 : std::vector<BQSBindQueueResult> &bindResultVec) const
307 : {
308 : (void)(bindQueueVec);
309 : (void)(bindResultVec);
310 1 : return 0;
311 : }
312 :
313 1 : uint32_t BqsClient::BindQueueInterChip(BindQueueInterChipInfo &interChipInfo) const
314 : {
315 : (void)(interChipInfo);
316 1 : return 0;
317 : }
318 :
319 1 : uint32_t BqsClient::UnbindQueueInterChip(uint16_t srcQueueId) const
320 : {
321 : (void)(srcQueueId);
322 1 : return 0;
323 : }
324 : } // namespace bqs
|