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