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 "aicpusd_resource_manager.h"
12 : #include <vector>
13 : #include <list>
14 : #include "aicpusd_status.h"
15 : #include "aicpusd_monitor.h"
16 : #include "aicpusd_util.h"
17 : #include "aicpusd_meminfo_process.h"
18 : #include "aicpusd_drv_manager.h"
19 :
20 : namespace {
21 : // mbuf address head align size.
22 : constexpr uint32_t MBUF_ALLOC_ALIGN_SIZE = 64U;
23 : constexpr int32_t MBUF_ALLOC_DEFAULT_GRP_ID = 0;
24 : constexpr size_t ONE_SIZE = 1UL;
25 : } // namespace
26 :
27 : namespace AicpuSchedule {
28 11021 : BufManager &BufManager::GetInstance()
29 : {
30 11021 : static BufManager instance;
31 11021 : return instance;
32 : }
33 :
34 122 : int32_t BufManager::GuardBuf(Mbuf *const mbuf, const uint32_t modelId)
35 : {
36 122 : if (mbuf == nullptr) {
37 2 : aicpusd_err("Guard buf failed as mbuf is null, modelId[%u].", modelId);
38 2 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
39 : }
40 120 : if (modelId >= MAX_MODEL_COUNT) {
41 0 : aicpusd_err("modelId[%u] over limit [%u].", modelId, MAX_MODEL_COUNT);
42 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
43 : }
44 120 : lockForModels_[modelId].Lock();
45 120 : modelBufs_[modelId].emplace_back(mbuf);
46 120 : lockForModels_[modelId].Unlock();
47 120 : return AICPU_SCHEDULE_OK;
48 : }
49 :
50 7 : Mbuf *BufManager::MallocBuf(const uint32_t allocSize)
51 : {
52 7 : return MallocBufU64(static_cast<uint64_t>(allocSize));
53 : }
54 :
55 66 : Mbuf *BufManager::MallocBufU64(const uint64_t allocSize)
56 : {
57 : // There is a test scenario that will pull up multi aicpu-scheduler,
58 : // if the memory pool is initialized in the main func will raise OOM error.
59 66 : auto drvRet = halBuffInit(&buffConfig_);
60 66 : if ((drvRet != DRV_ERROR_NONE) && (drvRet != DRV_ERROR_REPEATED_INIT)) {
61 0 : aicpusd_err("halBuffInit execute failed. ret[%d]", drvRet);
62 0 : return nullptr;
63 : }
64 :
65 66 : Mbuf *mbuf = nullptr;
66 66 : const uint64_t deviceId = static_cast<uint64_t>(AicpuDrvManager::GetInstance().GetDeviceId());
67 66 : const uint64_t flag = (deviceId << 32UL) | static_cast<uint64_t>(BUFF_SP_HUGEPAGE_PRIOR);
68 : // flag of buff to alloc(0~31bit:mem type, 32~35bit:devid, 36~63bit:resv)
69 66 : drvRet = halMbufAllocEx(static_cast<uint64_t>(allocSize), MBUF_ALLOC_ALIGN_SIZE,
70 : flag, MBUF_ALLOC_DEFAULT_GRP_ID, &mbuf);
71 66 : if (drvRet != DRV_ERROR_NONE) {
72 4 : aicpusd_err("Failed to alloc mbuf, size[%lu], ret[%d].", allocSize, drvRet);
73 4 : return nullptr;
74 : }
75 62 : drvRet = halMbufSetDataLen(mbuf, static_cast<uint64_t>(allocSize));
76 62 : if (drvRet != DRV_ERROR_NONE) {
77 1 : aicpusd_err("Failed to set mbuf data len, ret[%d].", drvRet);
78 1 : drvRet = halMbufFree(mbuf);
79 1 : if (drvRet != DRV_ERROR_NONE) {
80 1 : aicpusd_err("UnGuard Mbuf success but free by driver failed, ret[%d].", drvRet);
81 : }
82 1 : return nullptr;
83 : }
84 61 : return mbuf;
85 : }
86 :
87 42 : Mbuf *BufManager::MallocAndGuardBuf(const uint32_t allocSize, const uint32_t modelId)
88 : {
89 42 : return MallocAndGuardBufU64(static_cast<uint64_t>(allocSize), modelId);
90 : }
91 :
92 59 : Mbuf *BufManager::MallocAndGuardBufU64(const uint64_t allocSize, const uint32_t modelId)
93 : {
94 59 : Mbuf *mbuf = MallocBufU64(allocSize);
95 59 : if (mbuf == nullptr) {
96 8 : aicpusd_err("Failed to alloc mbuf for model[%u], size[%lu].", modelId, allocSize);
97 8 : return nullptr;
98 : }
99 51 : const int32_t guardRet = GuardBuf(mbuf, modelId);
100 51 : if (guardRet != AICPU_SCHEDULE_OK) {
101 1 : aicpusd_err("Failed to guard mbuf for model[%u], size[%lu], ret[%d].", modelId, allocSize, guardRet);
102 1 : const int32_t drvRet = halMbufFree(mbuf);
103 1 : if (drvRet != DRV_ERROR_NONE) {
104 1 : aicpusd_err("free by driver failed, ret[%d].", drvRet);
105 : }
106 1 : mbuf = nullptr;
107 : } else {
108 50 : aicpusd_info("Malloc and guard mbuf for model[%u], size[%lu].", modelId, allocSize);
109 : }
110 51 : return mbuf;
111 : }
112 :
113 7 : int32_t BufManager::MallocAndAppend(const uint32_t * const sizeList, const uint32_t idx, const uint32_t modelId,
114 : Mbuf *&mbuf, Mbuf *&mbufListHead)
115 : {
116 7 : mbuf = MallocBuf(sizeList[idx]);
117 7 : if (mbuf == nullptr) {
118 1 : aicpusd_err("Failed to alloc mbuf for model[%u], size[%u].", modelId, sizeList[idx]);
119 1 : AicpuMonitor::GetInstance().SendKillMsgToTsd();
120 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
121 : }
122 :
123 6 : int32_t ret = AICPU_SCHEDULE_OK;
124 6 : if (mbufListHead == nullptr) {
125 3 : mbufListHead = mbuf;
126 3 : ret = GuardBuf(mbuf, modelId);
127 3 : if (ret != AICPU_SCHEDULE_OK) {
128 1 : aicpusd_err("Failed to guard mbuf for model[%u], ret[%d].", modelId, ret);
129 1 : const int32_t drvRet = halMbufFree(mbuf);
130 1 : if (drvRet != DRV_ERROR_NONE) {
131 1 : aicpusd_err("free by driver failed, ret[%d].", drvRet);
132 : }
133 1 : mbuf = nullptr;
134 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
135 : }
136 : } else {
137 3 : ret = halMbufChainAppend(mbufListHead, mbuf);
138 3 : if (ret != DRV_ERROR_NONE) {
139 1 : aicpusd_err("halMbufChainAppend mbuf error.ret:%d", ret);
140 1 : const int32_t drvRet = halMbufFree(mbuf);
141 1 : if (drvRet != DRV_ERROR_NONE) {
142 0 : aicpusd_err("free by driver failed, ret[%d].", drvRet);
143 : }
144 1 : mbuf = nullptr;
145 1 : AicpuMonitor::GetInstance().SendKillMsgToTsd();
146 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
147 : }
148 : }
149 4 : return AICPU_SCHEDULE_OK;
150 : }
151 :
152 11 : int32_t BufManager::MallocAndGuardBufList(const uint32_t * const sizeList, const uint32_t len,
153 : const uint32_t modelId, const bool isLinkMbuf, Mbuf ** const mbufPtrStore)
154 : {
155 11 : if (sizeList == nullptr) {
156 0 : aicpusd_err("malloc sizeList is nullptr.");
157 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
158 : }
159 :
160 11 : int32_t ret = static_cast<uint32_t>(AICPU_SCHEDULE_OK);
161 11 : Mbuf *mbuf = nullptr;
162 11 : Mbuf *mbufListHead = nullptr;
163 :
164 : // free mbuf if error occur
165 0 : const ScopeGuard mbufGuard([&]() {
166 11 : if (mbuf != nullptr) {
167 0 : aicpusd_info("MallocAndGuardBufList guard release was not successful, ret:[%d]", ret);
168 : // do not set ret value by halMbufFree, keep ret value for function return
169 0 : const auto drvRet = halMbufFree(mbuf);
170 0 : if (drvRet != DRV_ERROR_NONE) {
171 0 : aicpusd_err("free by driver failed, ret[%d].", drvRet);
172 : }
173 0 : mbuf = nullptr;
174 : }
175 11 : });
176 30 : for (uint32_t i = 0U; i < len; i++) {
177 24 : mbuf = nullptr;
178 24 : if (!isLinkMbuf) {
179 17 : mbuf = MallocAndGuardBuf(sizeList[i], modelId);
180 17 : if (mbuf == nullptr) {
181 2 : aicpusd_err("Failed to alloc mbuf, dataSize[%u], modelId[%u].", sizeList[i], modelId);
182 2 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
183 : }
184 : } else {
185 7 : ret = MallocAndAppend(sizeList, i, modelId, mbuf, mbufListHead);
186 7 : if (ret != AICPU_SCHEDULE_OK) {
187 3 : return ret;
188 : }
189 : }
190 : // store every mbuf, set mbuf head outside
191 19 : mbufPtrStore[i] = mbuf;
192 : // set mbuf to nullptr otherwise, mbuf will be released
193 19 : mbuf = nullptr;
194 : }
195 :
196 6 : return AICPU_SCHEDULE_OK;
197 11 : }
198 :
199 29 : int32_t BufManager::UnGuardBuf(const uint32_t modelId, const Mbuf *const mbuf)
200 : {
201 29 : if (mbuf == nullptr) {
202 1 : aicpusd_err("UnGuard buf failed as mbuf is null.");
203 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
204 : }
205 28 : if (modelId >= MAX_MODEL_COUNT) {
206 0 : aicpusd_err("modelId[%u] over limit [%u].", modelId, MAX_MODEL_COUNT);
207 0 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
208 : }
209 28 : lockForModels_[modelId].Lock();
210 28 : std::list<Mbuf *> &bufList = modelBufs_[modelId];
211 53 : for (auto iter = bufList.begin(); iter != bufList.end(); ++iter) {
212 49 : if ((*iter) == mbuf) {
213 24 : iter = bufList.erase(iter);
214 24 : break;
215 : }
216 : }
217 28 : lockForModels_[modelId].Unlock();
218 28 : return AICPU_SCHEDULE_OK;
219 : }
220 :
221 544799 : void BufManager::FreeBuf(const uint32_t modelId)
222 : {
223 544799 : if (modelId >= MAX_MODEL_COUNT) {
224 6 : aicpusd_err("modelId[%u] over limit [%u].", modelId, MAX_MODEL_COUNT);
225 6 : return;
226 : }
227 544793 : lockForModels_[modelId].Lock();
228 544793 : std::list<Mbuf *> &mbufLst = modelBufs_[modelId];
229 544793 : if (mbufLst.empty()) {
230 544752 : lockForModels_[modelId].Unlock();
231 544752 : return;
232 : }
233 137 : for (Mbuf *const mbuf : mbufLst) {
234 96 : const auto drvRet = halMbufFree(mbuf);
235 96 : if (drvRet == static_cast<int32_t>(DRV_ERROR_NONE)) {
236 94 : aicpusd_info("Free Mbuf for model[%u] success.", modelId);
237 : } else {
238 2 : aicpusd_warn("Free Mbuf for model[%u] by driver failed, ret[%d].", modelId, drvRet);
239 : }
240 : }
241 41 : modelBufs_[modelId].clear();
242 41 : lockForModels_[modelId].Unlock();
243 41 : aicpusd_info("Free Mbuf for model[%u] end.", modelId);
244 : }
245 :
246 522 : void BufManager::FreeAllBuf()
247 : {
248 522 : aicpusd_info("Free all buff begin.");
249 535050 : for (uint32_t i = 0U; i < MAX_MODEL_COUNT; i++) {
250 534528 : FreeBuf(i);
251 : }
252 522 : aicpusd_info("Free all buff end.");
253 522 : }
254 :
255 13 : void BufManager::InitBufManager()
256 : {
257 13 : aicpusd_info("Aicpu schedule Init BufManager!");
258 13 : const auto ret = AicpuMemInfoProcess::GetMemZoneInfo(buffConfig_);
259 13 : if (ret != AICPU_SCHEDULE_OK) {
260 0 : aicpusd_run_info("Aicpu schedule SetBuffCfg retCode=[%u], buffConfig_ will use default value!", ret);
261 0 : buffConfig_ = {};
262 : } else {
263 13 : aicpusd_run_info("Aicpu schedule SetBuffCfg successfully!");
264 : }
265 13 : }
266 :
267 15443 : EventWaitManager &EventWaitManager::NotifyWaitManager(const uint32_t waitIdCount)
268 : {
269 15447 : static EventWaitManager notifyWaitInstance("Notify", waitIdCount);
270 15443 : return notifyWaitInstance;
271 : }
272 :
273 15432 : EventWaitManager &EventWaitManager::EndGraphWaitManager(const uint32_t waitIdCount)
274 : {
275 15436 : static EventWaitManager endGraphWaitInstance("EndGraph", waitIdCount);
276 15432 : return endGraphWaitInstance;
277 : }
278 :
279 123050 : EventWaitManager &EventWaitManager::QueueNotEmptyWaitManager(const uint32_t waitIdCount)
280 : {
281 123054 : static EventWaitManager queueNotEmptyWaitInstance("QueueNotEmpty", waitIdCount);
282 123050 : return queueNotEmptyWaitInstance;
283 : }
284 :
285 122991 : EventWaitManager &EventWaitManager::QueueNotFullWaitManager(const uint32_t waitIdCount)
286 : {
287 122995 : static EventWaitManager queueNotFullWaitInstance("QueueNotFull", waitIdCount);
288 122991 : return queueNotFullWaitInstance;
289 : }
290 :
291 46 : EventWaitManager &EventWaitManager::PrepareMemWaitManager(const uint32_t waitIdCount)
292 : {
293 50 : static EventWaitManager prepareMemWaitInstance("PrepareMem", waitIdCount);
294 46 : return prepareMemWaitInstance;
295 : }
296 :
297 64 : EventWaitManager &EventWaitManager::AnyQueNotEmptyWaitManager(const uint32_t waitIdCount)
298 : {
299 68 : static EventWaitManager anyQueNotEmptyWaitInstance("AnyQueNotEmpty", waitIdCount);
300 64 : return anyQueNotEmptyWaitInstance;
301 : }
302 :
303 48 : EventWaitManager &EventWaitManager::TableUnlockWaitManager(const uint32_t waitIdCount)
304 : {
305 52 : static EventWaitManager tableUnlockWaitInstance("TableUnlock", waitIdCount);
306 48 : return tableUnlockWaitInstance;
307 : }
308 :
309 27 : void EventWaitManager::Event(const size_t eventWaitId, bool &hasWait, uint32_t &waitStreamId)
310 : {
311 27 : if (CheckEvent(true, true, eventWaitId)) {
312 14 : return;
313 : }
314 26 : const std::unique_lock<std::mutex> lk(waitMutex_);
315 26 : eventState_[eventWaitId] = true;
316 26 : if (waitStream_[eventWaitId] == UINT32_MAX) {
317 13 : hasWait = false;
318 13 : aicpusd_info("[%s] eventWaitId[%zu] is come, but no stream is waiting. waitCount[%d]",
319 : eventType_.c_str(), eventWaitId, waitCount_);
320 13 : return;
321 : }
322 13 : waitStreamId = waitStream_[eventWaitId];
323 13 : hasWait = true;
324 13 : waitStream_[eventWaitId] = UINT32_MAX;
325 13 : --waitCount_;
326 13 : aicpusd_info("[%s] waitId[%zu] is come, stream[%u] is waiting. waitCount[%d]",
327 : eventType_.c_str(), eventWaitId, waitStreamId, waitCount_);
328 26 : }
329 :
330 25 : void EventWaitManager::WaitEvent(const size_t eventWaitId, const uint32_t waitStreamId, bool &needWait)
331 : {
332 25 : if (CheckEvent(true, true, eventWaitId)) {
333 23 : return;
334 : }
335 25 : const std::unique_lock<std::mutex> lk(waitMutex_);
336 25 : if (!eventState_[eventWaitId]) {
337 23 : waitStream_[eventWaitId] = waitStreamId;
338 23 : needWait = true;
339 23 : ++waitCount_;
340 23 : aicpusd_info("[%s] waitId[%zu] does not come, stream[%u] need wait. waitCount[%d]",
341 : eventType_.c_str(), eventWaitId, waitStreamId, waitCount_);
342 23 : return;
343 : }
344 :
345 : // reset state to false
346 2 : eventState_[eventWaitId] = false;
347 2 : needWait = false;
348 2 : aicpusd_info("[%s] WaitId[%zu] is come, stream[%u] no need wait. waitCount[%d]",
349 : eventType_.c_str(), eventWaitId, waitStreamId, waitCount_);
350 25 : }
351 :
352 4 : void EventWaitManager::GetWaitingEvent(std::vector<size_t> &eventWaitIds)
353 : {
354 4100 : for (size_t id = 0U; id < count_; ++id) {
355 4096 : if (waitStream_[id] != UINT32_MAX) {
356 1 : eventWaitIds.emplace_back(id);
357 : }
358 : }
359 4 : }
360 :
361 98 : void EventWaitManager::ResetEventState(const size_t eventWaitId)
362 : {
363 98 : if (CheckEvent(true, false, eventWaitId)) {
364 0 : return;
365 : }
366 98 : aicpusd_info("[%s] reset event state. waitId[%zu].", eventType_.c_str(), eventWaitId);
367 98 : const std::unique_lock<std::mutex> lk(waitMutex_);
368 98 : eventState_[eventWaitId] = false;
369 98 : }
370 :
371 253 : int32_t EventWaitManager::ClearBatch(const std::unordered_set<size_t> &waitIds)
372 : {
373 253 : if ((waitIds.empty()) || (CheckEvent(true, true, waitIds.size() - ONE_SIZE))) {
374 126 : return AICPU_SCHEDULE_OK;
375 : }
376 127 : aicpusd_info("[%s] clear records batch, waitIds.size[%zu].", eventType_.c_str(), waitIds.size());
377 127 : const std::unique_lock<std::mutex> lk(waitMutex_);
378 226 : for (const auto eventWaitId : waitIds) {
379 127 : if (eventWaitId >= count_) {
380 28 : aicpusd_err("[%s] waitId[%zu] invalid, should be in[0, %u).", eventType_.c_str(), eventWaitId, count_);
381 28 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
382 : }
383 99 : eventState_[eventWaitId] = false;
384 99 : waitStream_[eventWaitId] = UINT32_MAX;
385 : }
386 99 : return AICPU_SCHEDULE_OK;
387 127 : }
388 :
389 299 : bool EventWaitManager::CheckEvent(const bool eventStateNeedCheck, const bool waitStreamNeedCheck,
390 : const size_t length)
391 : {
392 299 : const std::unique_lock<std::mutex> lk(waitMutex_);
393 299 : if (eventStateNeedCheck) {
394 298 : if (length >= eventState_.size()) {
395 2 : aicpusd_warn("eventState_ check failed, size[%zu], input value[%zu].", eventState_.size(), length);
396 2 : return true;
397 : }
398 : }
399 297 : if (waitStreamNeedCheck) {
400 199 : if (length >= waitStream_.size()) {
401 1 : aicpusd_warn("waitStream_ check failed, size[%zu], input value[%zu].", waitStream_.size(), length);
402 1 : return true;
403 : }
404 : }
405 296 : return false;
406 299 : }
407 :
408 70 : ModelStreamManager &ModelStreamManager::GetInstance()
409 : {
410 70 : static ModelStreamManager instance;
411 70 : return instance;
412 : }
413 :
414 20 : void ModelStreamManager::Reg(const uint32_t modelId, const std::vector<StreamInfo> &streams)
415 : {
416 20 : std::lock_guard<std::mutex> lk(streamInfoMtx_);
417 112 : for (const auto &stream : streams) {
418 92 : const auto &ret = streamInfos_.emplace(stream.streamID, std::pair<uint32_t, uint32_t>(modelId,
419 92 : stream.streamFlag));
420 92 : if (!ret.second) {
421 5 : aicpusd_err("Reg stream failed, streamId=%u, modelId=%u, streamFlag=%u",
422 : stream.streamID, modelId, stream.streamFlag);
423 : } else {
424 87 : aicpusd_info("Reg stream success, streamId=%u, modelId=%u, streamFlag=%u, size=%lu",
425 : stream.streamID, modelId, stream.streamFlag, streamInfos_.size());
426 : }
427 : }
428 :
429 40 : return;
430 20 : }
431 :
432 25 : void ModelStreamManager::UnReg(const uint32_t modelId, const std::vector<StreamInfo> &streams)
433 : {
434 25 : std::lock_guard<std::mutex> lk(streamInfoMtx_);
435 113 : for (const auto &stream : streams) {
436 88 : const auto &iter = streamInfos_.find(stream.streamID);
437 88 : if (iter != streamInfos_.end()) {
438 87 : if (iter->second.first == modelId) {
439 86 : aicpusd_info("UnReg stream success, streamId=%u, modelId=%u, size=%lu",
440 : stream.streamID, modelId, streamInfos_.size());
441 86 : (void)streamInfos_.erase(stream.streamID);
442 : } else {
443 1 : aicpusd_warn("UnReg stream[%u] failed, as param modelId[%u] but stream modelId[%u].",
444 : stream.streamID, modelId, iter->second.first);
445 : }
446 : }
447 : }
448 :
449 50 : return;
450 25 : }
451 :
452 14 : int32_t ModelStreamManager::GetStreamFlag(const uint32_t streamId, uint32_t &streamFlag)
453 : {
454 14 : std::lock_guard<std::mutex> lk(streamInfoMtx_);
455 14 : const auto &iter = streamInfos_.find(streamId);
456 14 : if (iter == streamInfos_.end()) {
457 2 : aicpusd_err("Cannot find stream, streamId=%u", streamId);
458 2 : return AICPU_SCHEDULE_ERROR_STREAM_NOT_FOUND;
459 : }
460 :
461 12 : streamFlag = iter->second.second;
462 :
463 12 : return AICPU_SCHEDULE_OK;
464 14 : }
465 :
466 3 : int32_t ModelStreamManager::GetStreamModelId(const uint32_t streamId, uint32_t &modelId)
467 : {
468 3 : std::lock_guard<std::mutex> lk(streamInfoMtx_);
469 3 : const auto &iter = streamInfos_.find(streamId);
470 3 : if (iter == streamInfos_.end()) {
471 2 : aicpusd_err("Cannot find stream, streamId=%u", streamId);
472 2 : return AICPU_SCHEDULE_ERROR_STREAM_NOT_FOUND;
473 : }
474 :
475 1 : modelId = iter->second.first;
476 :
477 1 : return AICPU_SCHEDULE_OK;
478 3 : }
479 :
480 210 : TableLockManager &TableLockManager::GetInstance()
481 : {
482 210 : static TableLockManager instance;
483 210 : return instance;
484 : }
485 :
486 210 : RwLock &TableLockManager::GetTableLock(const uint32_t tableId)
487 : {
488 210 : const std::unique_lock<std::mutex> lockForTableLocks(mutexForLockMap_);
489 210 : if (tableLocks_.find(tableId) == tableLocks_.end()) {
490 2 : tableLocks_[tableId].Init();
491 : }
492 420 : return tableLocks_[tableId];
493 210 : }
494 :
495 3 : bool TableLockManager::RdLockTable(const uint32_t tableId)
496 : {
497 3 : aicpusd_info("rdlock table %u.", tableId);
498 3 : auto &tableLock = GetTableLock(tableId);
499 3 : return tableLock.RdLock();
500 : }
501 :
502 2 : bool TableLockManager::WrLockTable(const uint32_t tableId)
503 : {
504 2 : aicpusd_info("wrlock table %u.", tableId);
505 2 : auto &tableLock = GetTableLock(tableId);
506 2 : return tableLock.WrLock();
507 : }
508 :
509 205 : void TableLockManager::UnLockTable(const uint32_t tableId)
510 : {
511 205 : aicpusd_info("unlock table %u.", tableId);
512 205 : auto &tableLock = GetTableLock(tableId);
513 205 : tableLock.UnLock();
514 205 : }
515 :
516 2 : void RwLock::Init()
517 : {
518 2 : readCount_ = 0U;
519 2 : writeCount_ = 0U;
520 2 : }
521 :
522 3 : bool RwLock::RdLock()
523 : {
524 3 : const std::unique_lock<std::mutex> lockForCount(mu_);
525 3 : if (writeCount_ > 0U) {
526 2 : aicpusd_info("This lock has been locked by write, cannot rdLock now.");
527 2 : return false;
528 : }
529 1 : ++readCount_;
530 1 : aicpusd_info("rdlock success");
531 1 : return true;
532 3 : }
533 :
534 2 : bool RwLock::WrLock()
535 : {
536 2 : const std::unique_lock<std::mutex> lockForCount(mu_);
537 2 : if ((writeCount_ > 0U) || (readCount_ > 0U)) {
538 0 : aicpusd_info("Current writeCount[%u], readCount[%u], cannot WrLock now.", writeCount_, readCount_);
539 0 : return false;
540 : }
541 2 : ++writeCount_;
542 2 : aicpusd_info("wrlock success");
543 2 : return true;
544 2 : }
545 :
546 205 : void RwLock::UnLock()
547 : {
548 205 : const std::unique_lock<std::mutex> lockForCount(mu_);
549 205 : if (writeCount_ > 0U) {
550 2 : aicpusd_info("unlock write lock, current write count is %u", writeCount_);
551 2 : --writeCount_;
552 2 : return;
553 : }
554 :
555 203 : if (readCount_ > 0U) {
556 1 : aicpusd_info("unlock read lock, current read count is %u", readCount_);
557 1 : --readCount_;
558 1 : return;
559 : }
560 202 : aicpusd_warn("Three's no lock");
561 205 : }
562 : }
|