LCOV - code coverage report
Current view: top level - server - queue_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.7 % 426 416
Test Date: 2026-08-12 11:05:07 Functions: 100.0 % 32 32

            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 "queue_manager.h"
      12              : 
      13              : #include <cstring>
      14              : #include <securec.h>
      15              : #include "driver/ascend_hal.h"
      16              : #include "bqs_msg.h"
      17              : #include "subscribe_manager.h"
      18              : #include "statistic_manager.h"
      19              : #include "server/bqs_server.h"
      20              : #include "router_server.h"
      21              : #include "common/bqs_util.h"
      22              : 
      23              : namespace bqs {
      24              : namespace {
      25              : constexpr const char_t* RELATION_QUEUE_NAME = "QSRelationEvent";
      26              : constexpr const char_t* F2NF_QUEUE_NAME = "QSF2NFEvent";
      27              : constexpr const char_t* ASYNC_MEM_BUFF_DEQ_QUEUE_NAME = "QSAsyncMemDeBuffEvent";
      28              : constexpr const char_t* ASYNC_MEM_BUFF_ENQ_QUEUE_NAME = "QSAsyncMemEnBuffEvent";
      29              : // relation message type enqueue message length
      30              : constexpr const uint32_t BIND_EVENT_MSG_LENGTH(1U);
      31              : constexpr const uint32_t MAX_QUEUE_DEPTH = 8U * 1024U;
      32              : constexpr const uint32_t MAX_DEQUEUE_COUNT = MAX_QUEUE_DEPTH;
      33              : constexpr const char_t* RELATION_QUEUE_NAME_EXTRA = "QSRelationEventExtra";
      34              : constexpr const char_t* F2NF_QUEUE_NAME_EXTRA = "QSF2NFEventExtra";
      35              : } // namespace
      36              : 
      37           49 : QueueManager::QueueManager()
      38           49 :     : deviceId_(0U),
      39           49 :       groupId_(0U),
      40           49 :       relationEventQId_(0U),
      41           49 :       fullToNotFullEventQId_(0U),
      42           49 :       asyncMemDequeueBuffQId_(0),
      43           49 :       asyncMemEnqueueBuffQId_(0),
      44           49 :       initialized_(false),
      45           49 :       stopped_(false),
      46           49 :       f2nfQueueEmptyFlag_(true),
      47           49 :       mbufForF2nf_(nullptr),
      48           49 :       relationEventQInitialized_(false),
      49           49 :       fullToNotFullEventQInitialized_(false),
      50           49 :       deviceIdExtra_(0U),
      51           49 :       groupIdExtra_(0U),
      52           49 :       relationEventQIdExtra_(0U),
      53           49 :       relationEventQInitializedExtra_(false),
      54           49 :       fullToNotFullEventQIdExtra_(0U),
      55           49 :       fullToNotFullEventQInitializedExtra_(false),
      56           49 :       mbufForF2nfExtra_(nullptr),
      57           49 :       f2nfQueueEmptyFlagExtra_(true),
      58           49 :       isTriggeredByAsyncMemDequeue_(false),
      59           49 :       isTriggeredByAsyncMemEnqueue_(false),
      60           49 :       ayncMemBuffEventQInitialized_(false),
      61           98 :       initiallizedExtra_(false)
      62           49 : {}
      63              : 
      64           49 : QueueManager::~QueueManager() { Clear(); }
      65              : 
      66          254 : QueueManager& QueueManager::GetInstance()
      67              : {
      68          254 :     static QueueManager instance;
      69          254 :     return instance;
      70              : }
      71              : 
      72          206 : BqsStatus QueueManager::CreateQueue(
      73              :     const char_t* const name, const uint32_t depth, uint32_t& queueId, uint32_t deviceId) const
      74              : {
      75          206 :     std::string nameStr(name);
      76          206 :     const auto curPid = static_cast<uint32_t>(drvDeviceGetBareTgid());
      77          206 :     nameStr += std::to_string(curPid);
      78          206 :     QueueAttr queAttr = {};
      79              :     const auto memcpyRet =
      80          206 :         memcpy_s(queAttr.name, static_cast<uint32_t>(QUEUE_MAX_STR_LEN), nameStr.c_str(), nameStr.length());
      81          206 :     if (memcpyRet != EOK) {
      82            0 :         BQS_LOG_ERROR("CreateAndSubscribeQueue memcpy_s failed, ret[%d].", memcpyRet);
      83            0 :         return BQS_STATUS_INNER_ERROR;
      84              :     }
      85          206 :     queAttr.depth = depth;
      86          206 :     queAttr.deploy_type = CLIENT_QUEUE_DEPLOY;
      87          206 :     if (bqs::GetRunContext() == bqs::RunContext::HOST) {
      88          184 :         queAttr.deploy_type = LOCAL_QUEUE_DEPLOY;
      89              :     }
      90          206 :     BQS_LOG_INFO("CreateAndSubscribeQueue queue depth[%d]", depth);
      91          206 :     const drvError_t ret = halQueueCreate(deviceId, &queAttr, &queueId);
      92          206 :     if (ret != DRV_ERROR_NONE) {
      93            4 :         BQS_LOG_ERROR("Create buff queue[%s] error, ret=%d", nameStr.c_str(), static_cast<int32_t>(ret));
      94            4 :         return BQS_STATUS_DRIVER_ERROR;
      95              :     }
      96          202 :     const drvError_t drvRet = halQueueAttach(deviceId, queueId, 0);
      97          202 :     if (drvRet != DRV_ERROR_NONE) {
      98            1 :         BQS_LOG_ERROR("Fail to attach queue[%ud], result[%d]", queueId, static_cast<int32_t>(drvRet));
      99            1 :         (void)DestroyQueue(queueId);
     100            1 :         return BQS_STATUS_DRIVER_ERROR;
     101              :     }
     102          201 :     BQS_LOG_RUN_INFO("Create buff queue[%s] on device[%u] success, queue[%u].", nameStr.c_str(), deviceId, queueId);
     103          201 :     return BQS_STATUS_OK;
     104          206 : }
     105              : 
     106          187 : BqsStatus QueueManager::CreateQueue(const char_t* const name, const uint32_t depth, uint32_t& queueId) const
     107              : {
     108          187 :     return CreateQueue(name, depth, queueId, deviceId_);
     109              : }
     110              : 
     111          187 : BqsStatus QueueManager::CreateAndSubscribeQueue(const char_t* const name, const uint32_t depth, uint32_t& queueId) const
     112              : {
     113          187 :     const BqsStatus ret = CreateQueue(name, depth, queueId);
     114          187 :     if (ret != BQS_STATUS_OK) {
     115            3 :         BQS_LOG_ERROR("Create buff queue[name:%s, depth:%u] failed, ret=%d.", name, depth, static_cast<int32_t>(ret));
     116            3 :         return ret;
     117              :     }
     118              : 
     119          184 :     drvError_t drvRet = DRV_ERROR_NONE;
     120          184 :     if (bqs::GetRunContext() != bqs::RunContext::HOST) {
     121           20 :         drvRet = halQueueSubscribe(deviceId_, queueId, groupId_, QUEUE_TYPE_GROUP);
     122              :     } else {
     123              :         struct QueueSubPara queSubParm;
     124          164 :         queSubParm.eventType = QUEUE_ENQUE_EVENT;
     125          164 :         queSubParm.qid = queueId;
     126          164 :         queSubParm.queType = QUEUE_TYPE_GROUP;
     127          164 :         queSubParm.groupId = groupId_;
     128          164 :         queSubParm.devId = deviceId_;
     129          164 :         queSubParm.flag = 0;
     130          164 :         drvRet = halQueueSubEvent(&queSubParm);
     131              :     }
     132              : 
     133          184 :     if (drvRet != DRV_ERROR_NONE) {
     134            2 :         BQS_LOG_ERROR(
     135              :             "Subscribe buff queue[name:%s, id:%u] failed, deviceId[%u], groupId[%u], ret=%d.", name, queueId, deviceId_,
     136              :             groupId_, static_cast<int32_t>(drvRet));
     137            2 :         (void)DestroyQueue(queueId);
     138            2 :         return BQS_STATUS_DRIVER_ERROR;
     139              :     }
     140          182 :     BQS_LOG_INFO(
     141              :         "Subscribe buff queue[name:%s, id:%u] success, deviceId[%u], groupId[%u]", name, queueId, deviceId_, groupId_);
     142          182 :     return BQS_STATUS_OK;
     143              : }
     144              : 
     145           10 : BqsStatus QueueManager::CreateAndSubscribeQueueExtra(
     146              :     const char_t* const name, const uint32_t depth, uint32_t& queueId) const
     147              : {
     148           10 :     const BqsStatus ret = CreateQueue(name, depth, queueId, deviceIdExtra_);
     149           10 :     if (ret != BQS_STATUS_OK) {
     150            1 :         BQS_LOG_ERROR("Create buff queue[name:%s, depth:%u] failed, ret=%d.", name, depth, static_cast<int32_t>(ret));
     151            1 :         return ret;
     152              :     }
     153              : 
     154            9 :     const drvError_t drvRet = halQueueSubscribe(deviceIdExtra_, queueId, groupIdExtra_, QUEUE_TYPE_GROUP);
     155            9 :     if (drvRet != DRV_ERROR_NONE) {
     156            1 :         BQS_LOG_ERROR(
     157              :             "Subscribe buff queue[name:%s, id:%u] failed, deviceId[%u], groupId[%u], ret=%d.", name, queueId,
     158              :             deviceIdExtra_, groupIdExtra_, static_cast<int32_t>(drvRet));
     159            1 :         (void)DestroyQueue(queueId, deviceIdExtra_);
     160            1 :         return BQS_STATUS_DRIVER_ERROR;
     161              :     }
     162            8 :     BQS_LOG_INFO(
     163              :         "Subscribe buff queue[name:%s, id:%u] success, deviceId[%u], groupId[%u].", name, queueId, deviceIdExtra_,
     164              :         groupIdExtra_);
     165            8 :     return BQS_STATUS_OK;
     166              : }
     167              : 
     168          189 : BqsStatus QueueManager::DestroyQueue(const uint32_t queueId) const { return DestroyQueue(queueId, deviceId_); }
     169              : 
     170          206 : BqsStatus QueueManager::DestroyQueue(const uint32_t queueId, uint32_t deviceId) const
     171              : {
     172          206 :     const int32_t ret = halQueueDestroy(deviceId, queueId);
     173          206 :     if (ret != static_cast<int32_t>(DRV_ERROR_NONE)) {
     174            9 :         BQS_LOG_ERROR("halQueueDestroy failed, queue id:[%u], ret:[%d]", queueId, ret);
     175            9 :         return BQS_STATUS_DRIVER_ERROR;
     176              :     }
     177          197 :     BQS_LOG_RUN_INFO("Destroy queue[%u] on deviceId[%u] success.", queueId, deviceId);
     178          197 :     return BQS_STATUS_OK;
     179              : }
     180              : 
     181          187 : BqsStatus QueueManager::UnsubscribeQueue(const uint32_t queueId, const QUEUE_EVENT_TYPE eventType) const
     182              : {
     183          187 :     auto status = DRV_ERROR_NONE;
     184          187 :     if (bqs::GetRunContext() != bqs::RunContext::HOST) {
     185           20 :         status = halQueueUnsubscribe(deviceId_, queueId);
     186              :     } else {
     187              :         struct QueueUnsubPara queUnsubParm;
     188          167 :         queUnsubParm.eventType = eventType;
     189          167 :         queUnsubParm.qid = queueId;
     190          167 :         queUnsubParm.devId = deviceId_;
     191          167 :         status = halQueueUnsubEvent(&queUnsubParm);
     192              :     }
     193              : 
     194          187 :     if ((status != DRV_ERROR_NONE) && (status != DRV_ERROR_NOT_EXIST)) {
     195            1 :         BQS_LOG_ERROR("halQueueUnsubscribe queue[%u] failed, ret=%d.", queueId, static_cast<int32_t>(status));
     196            1 :         return BQS_STATUS_DRIVER_ERROR;
     197              :     }
     198          186 :     return BQS_STATUS_OK;
     199              : }
     200              : 
     201              : /**
     202              :  * init/create/subscribe buff queue
     203              :  * @return BQS_STATUS_OK:success other:failed
     204              :  */
     205           50 : BqsStatus QueueManager::InitQueueManager(
     206              :     const uint32_t deviceId, const uint32_t groupId, const bool hasAICPU, const std::string& groupName)
     207              : {
     208              :     (void)hasAICPU;
     209           50 :     deviceId_ = deviceId;
     210           50 :     groupId_ = groupId;
     211           50 :     grpName_ = groupName;
     212           50 :     BQS_LOG_INFO(
     213              :         "QueueManager init begin, deviceId[%u], groupId[%u], groupName[%s].", deviceId, groupId, grpName_.c_str());
     214              : 
     215           50 :     if (!groupName.empty()) {
     216           50 :         const auto queueInitRet = InitQueue();
     217           50 :         if (queueInitRet != BQS_STATUS_OK) {
     218            6 :             BQS_LOG_ERROR("QueueManager Init failed, deviceId[%u], groupId[%u]", deviceId, groupId);
     219            6 :             return queueInitRet;
     220              :         }
     221              :     }
     222              : 
     223           44 :     BQS_LOG_INFO("QueueManager init success, deviceId[%u], groupId[%u].", deviceId, groupId);
     224           44 :     return BQS_STATUS_OK;
     225              : }
     226              : 
     227            5 : void QueueManager::InitExtra(const uint32_t deviceIdExtra, const uint32_t groupIdExtra)
     228              : {
     229            5 :     deviceIdExtra_ = deviceIdExtra;
     230            5 :     groupIdExtra_ = groupIdExtra;
     231            5 :     if (!grpName_.empty()) {
     232            4 :         const auto queueInitRet = InitQueueExtra();
     233            4 :         if (queueInitRet != BQS_STATUS_OK) {
     234            0 :             BQS_LOG_ERROR("QueueManager Init failed, deviceId[%u], groupId[%u]", deviceIdExtra, groupIdExtra);
     235              :         }
     236              :     }
     237            5 : }
     238              : 
     239            7 : BqsStatus QueueManager::InitQueueExtra()
     240              : {
     241            7 :     BQS_LOG_INFO("InitQueueExtra begin, deviceId[%u].", deviceIdExtra_);
     242            7 :     const auto ret = halQueueInit(deviceIdExtra_);
     243            7 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_REPEATED_INIT)) {
     244            1 :         BQS_LOG_ERROR("halQueueInit error, ret=[%d]", static_cast<int32_t>(ret));
     245            1 :         return BQS_STATUS_DRIVER_ERROR;
     246              :     }
     247              : 
     248            6 :     BqsStatus bqsRet = CreateAndSubscribeQueueExtra(RELATION_QUEUE_NAME_EXTRA, MAX_QUEUE_DEPTH, relationEventQIdExtra_);
     249            6 :     if (bqsRet != BQS_STATUS_OK) {
     250            1 :         BQS_LOG_ERROR("Create and subscribe relation queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     251            1 :         return bqsRet;
     252              :     }
     253            5 :     relationEventQInitializedExtra_ = true;
     254            5 :     BQS_LOG_INFO("InitQueue[%u] success, deviceId[%u].", relationEventQIdExtra_, deviceIdExtra_);
     255              : 
     256            5 :     bqsRet = CreateAndSubscribeQueueExtra(F2NF_QUEUE_NAME_EXTRA, MAX_QUEUE_DEPTH, fullToNotFullEventQIdExtra_);
     257            5 :     if (bqsRet != BQS_STATUS_OK) {
     258            1 :         BQS_LOG_ERROR("Create and subscribe F2NF queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     259            1 :         return bqsRet;
     260              :     }
     261            4 :     fullToNotFullEventQInitializedExtra_ = true;
     262            4 :     return BQS_STATUS_OK;
     263              : }
     264              : 
     265           54 : BqsStatus QueueManager::InitQueue()
     266              : {
     267           54 :     BQS_LOG_INFO("InitQueue begin, deviceId[%u].", deviceId_);
     268           54 :     if (bqs::GetRunContext() == bqs::RunContext::HOST) {
     269              :         // local need queue set
     270              :         QueueSetInputPara inPutParam;
     271           49 :         (void)halQueueSet(deviceId_, QUEUE_ENABLE_LOCAL_QUEUE, &inPutParam);
     272              :     }
     273              : 
     274           54 :     const auto ret = halQueueInit(deviceId_);
     275           54 :     if ((ret != DRV_ERROR_NONE) && (ret != DRV_ERROR_REPEATED_INIT)) {
     276            2 :         BQS_LOG_ERROR("halQueueInit error, ret=[%d]", static_cast<int32_t>(ret));
     277            2 :         return BQS_STATUS_DRIVER_ERROR;
     278              :     }
     279              : 
     280           52 :     BqsStatus bqsRet = CreateAndSubscribeQueue(RELATION_QUEUE_NAME, MAX_QUEUE_DEPTH, relationEventQId_);
     281           52 :     if (bqsRet != BQS_STATUS_OK) {
     282            3 :         BQS_LOG_ERROR("Create and subscribe relation queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     283            3 :         return bqsRet;
     284              :     }
     285           49 :     relationEventQInitialized_ = true;
     286              : 
     287           49 :     bqsRet = CreateAndSubscribeQueue(F2NF_QUEUE_NAME, MAX_QUEUE_DEPTH, fullToNotFullEventQId_);
     288           49 :     if (bqsRet != BQS_STATUS_OK) {
     289            2 :         BQS_LOG_ERROR("Create and subscribe F2NF queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     290            2 :         return bqsRet;
     291              :     }
     292           47 :     fullToNotFullEventQInitialized_ = true;
     293              : 
     294           47 :     bqsRet = CreateAndSubscribeQueue(ASYNC_MEM_BUFF_DEQ_QUEUE_NAME, MAX_QUEUE_DEPTH, asyncMemDequeueBuffQId_);
     295           47 :     if (bqsRet != BQS_STATUS_OK) {
     296            1 :         BQS_LOG_ERROR("Create and subscribe AsyncMemBuff queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     297            1 :         return bqsRet;
     298              :     }
     299              : 
     300           46 :     bqsRet = CreateAndSubscribeQueue(ASYNC_MEM_BUFF_ENQ_QUEUE_NAME, MAX_QUEUE_DEPTH, asyncMemEnqueueBuffQId_);
     301           46 :     if (bqsRet != BQS_STATUS_OK) {
     302            1 :         BQS_LOG_ERROR("Create and subscribe AsyncMemBuff queue error, ret=[%d]", static_cast<int32_t>(bqsRet));
     303            1 :         return bqsRet;
     304              :     }
     305           45 :     ayncMemBuffEventQInitialized_ = true;
     306              : 
     307           45 :     BQS_LOG_INFO("InitQueue success, deviceId[%u]", deviceId_);
     308           45 :     return BQS_STATUS_OK;
     309              : }
     310              : 
     311              : /**
     312              :  * destroy buff queue
     313              :  * @return NA
     314              :  */
     315           60 : void QueueManager::Destroy()
     316              : {
     317           60 :     BQS_LOG_INFO("QueueManager Destroy begin");
     318              : 
     319              :     {
     320           60 :         const std::unique_lock<std::mutex> destroyLock(mutex_);
     321           60 :         stopped_ = true;
     322           60 :         cv_.notify_all();
     323           60 :     }
     324              : 
     325           60 :     Clear();
     326           60 :     BQS_LOG_INFO("QueueManager Destroy success");
     327           60 :     return;
     328              : }
     329              : 
     330          111 : void QueueManager::Clear()
     331              : {
     332          111 :     if (mbufForF2nf_ != nullptr) {
     333            1 :         (void)halMbufFree(mbufForF2nf_);
     334            1 :         mbufForF2nf_ = nullptr;
     335              :     }
     336              : 
     337          111 :     if (mbufForF2nfExtra_ != nullptr) {
     338            1 :         (void)halMbufFree(mbufForF2nfExtra_);
     339            1 :         mbufForF2nfExtra_ = nullptr;
     340              :     }
     341              : 
     342          111 :     if (relationEventQInitialized_) {
     343           49 :         ClearQueue(relationEventQId_, QUEUE_ENQUE_EVENT);
     344           49 :         relationEventQInitialized_ = false;
     345              :     }
     346              : 
     347          111 :     if (relationEventQInitializedExtra_) {
     348            5 :         halQueueUnsubscribe(deviceIdExtra_, relationEventQIdExtra_);
     349            5 :         (void)DestroyQueue(relationEventQIdExtra_, deviceIdExtra_);
     350            5 :         relationEventQInitializedExtra_ = false;
     351              :     }
     352              : 
     353          111 :     if (fullToNotFullEventQInitialized_) {
     354           47 :         ClearQueue(fullToNotFullEventQId_, QUEUE_F2NF_EVENT);
     355           47 :         fullToNotFullEventQInitialized_ = false;
     356              :     }
     357              : 
     358          111 :     if (fullToNotFullEventQInitializedExtra_) {
     359            4 :         halQueueUnsubscribe(deviceIdExtra_, fullToNotFullEventQIdExtra_);
     360            4 :         (void)DestroyQueue(fullToNotFullEventQIdExtra_, deviceIdExtra_);
     361            4 :         fullToNotFullEventQInitializedExtra_ = false;
     362              :     }
     363              : 
     364          111 :     if (ayncMemBuffEventQInitialized_) {
     365           45 :         ClearQueue(asyncMemDequeueBuffQId_, QUEUE_ENQUE_EVENT);
     366           45 :         ClearQueue(asyncMemEnqueueBuffQId_, QUEUE_ENQUE_EVENT);
     367           45 :         ayncMemBuffEventQInitialized_ = false;
     368              :     }
     369          111 : }
     370              : 
     371          186 : void QueueManager::ClearQueue(const uint32_t queueId, const QUEUE_EVENT_TYPE eventType) const
     372              : {
     373          186 :     (void)UnsubscribeQueue(queueId, eventType);
     374          186 :     (void)DestroyQueue(queueId);
     375          186 : }
     376              : 
     377              : /**
     378              :  * work thread init success will notify queue manager
     379              :  * @return NA
     380              :  */
     381          161 : void QueueManager::NotifyInitSuccess(const uint32_t index)
     382              : {
     383          161 :     const std::unique_lock<std::mutex> notifyLock(mutex_);
     384          164 :     if (!initialized_ && (index == 0U)) {
     385           50 :         initialized_ = true;
     386           50 :         cv_.notify_all();
     387           50 :         BQS_LOG_INFO("Queue schedule init success.");
     388          114 :     } else if (!initiallizedExtra_ && (index == 1U)) {
     389            1 :         initiallizedExtra_ = true;
     390            1 :         cv_.notify_all();
     391            1 :         BQS_LOG_INFO("Queue schedule extra init success.");
     392              :     }
     393          328 :     return;
     394          164 : }
     395              : 
     396            5 : BqsStatus QueueManager::EnqueueRelationEvent()
     397              : {
     398              :     {
     399              :         // wait for work thread halEschedWaitEvent execute
     400            5 :         std::unique_lock<std::mutex> equeueRelationEventLock(mutex_);
     401            6 :         while ((!initialized_) && (!stopped_)) {
     402            1 :             BQS_LOG_INFO("Relation msg enqueue wait for init success.");
     403            1 :             cv_.wait(equeueRelationEventLock);
     404            1 :             std::this_thread::sleep_for(std::chrono::milliseconds(1));
     405              :         }
     406              : 
     407            5 :         if (stopped_) {
     408            1 :             BQS_LOG_INFO("Queue manager has been stopped, no need to enqueue relation.");
     409            1 :             return BQS_STATUS_OK;
     410              :         }
     411            5 :     }
     412              : 
     413            4 :     return EnqueueRelationEventToQ(deviceId_, relationEventQId_);
     414              : }
     415              : 
     416            1 : BqsStatus QueueManager::EnqueueRelationEventExtra()
     417              : {
     418              :     {
     419              :         // wait for work thread halEschedWaitEvent execute
     420            1 :         std::unique_lock<std::mutex> equeueRelationEventLock(mutex_);
     421            1 :         while ((!initiallizedExtra_) && (!stopped_)) {
     422            0 :             BQS_LOG_INFO("Relation msg enqueue wait for init success.");
     423            0 :             cv_.wait(equeueRelationEventLock);
     424            0 :             std::this_thread::sleep_for(std::chrono::milliseconds(1));
     425              :         }
     426              : 
     427            1 :         if (stopped_) {
     428            1 :             BQS_LOG_INFO("Queue manager has been stopped, no need to enqueue relation.");
     429            1 :             return BQS_STATUS_OK;
     430              :         }
     431            1 :     }
     432            0 :     return EnqueueRelationEventToQ(deviceIdExtra_, relationEventQIdExtra_);
     433              : }
     434              : /**
     435              :  * Enqueue a data to implies that the client sent a message
     436              :  * @return BQS_STATUS_OK:success other:failed
     437              :  */
     438            4 : BqsStatus QueueManager::EnqueueRelationEventToQ(const uint32_t deviceId, const uint32_t relationEventQ) const
     439              : {
     440            4 :     BQS_LOG_INFO("QueueManager EnqueueRelationEvent begin");
     441              : 
     442            4 :     Mbuf* mbufPtr = nullptr;
     443            4 :     int32_t ret = halMbufAlloc(BIND_EVENT_MSG_LENGTH, &mbufPtr);
     444            4 :     if (ret != DRV_ERROR_NONE) {
     445            1 :         BQS_LOG_ERROR("halMbufAlloc error, queue id:[%u], ret=[%d]", relationEventQ, ret);
     446            1 :         return BQS_STATUS_DRIVER_ERROR;
     447              :     }
     448              : 
     449            3 :     ret = halQueueEnQueue(deviceId, relationEventQ, mbufPtr);
     450            3 :     if (ret != DRV_ERROR_NONE) {
     451            1 :         BQS_LOG_ERROR("halQueueEnQueue error, queue id:[%u], ret=[%d]", relationEventQ, ret);
     452            1 :         (void)halMbufFree(mbufPtr);
     453            1 :         return BQS_STATUS_DRIVER_ERROR;
     454              :     }
     455            2 :     StatisticManager::GetInstance().RelationEnqueueStat();
     456            2 :     BQS_LOG_INFO("QueueManager EnqueueRelationEvent end, queueId[%u] deviceId[%u]", relationEventQ, deviceId);
     457            2 :     return BQS_STATUS_OK;
     458              : }
     459              : 
     460              : /**
     461              :  * handle the bind or unbind msg that the client sent
     462              :  * @return true:has handle relation msg, false:not handle
     463              :  */
     464            6 : bool QueueManager::HandleRelationEvent(const uint32_t index) const
     465              : {
     466            6 :     bool dequeue = false;
     467            6 :     Mbuf* mbufPtr = nullptr;
     468            6 :     int32_t ret = DRV_ERROR_NONE;
     469            6 :     auto deviceId = (index == 0U) ? deviceId_ : deviceIdExtra_;
     470            6 :     auto relationEventQId = (index == 0U) ? relationEventQId_ : relationEventQIdExtra_;
     471              :     while (true) {
     472            9 :         ret = halQueueDeQueue(deviceId, relationEventQId, PtrToPtr<Mbuf*, void*>(&mbufPtr));
     473            9 :         if (ret == DRV_ERROR_QUEUE_EMPTY) {
     474            5 :             break;
     475              :         }
     476              : 
     477            4 :         BQS_LOG_INFO("HandleRelationEvent dequeue deviceId[%u], relationQ[%u]", deviceId, relationEventQId);
     478            4 :         if (ret != DRV_ERROR_NONE) {
     479            1 :             BQS_LOG_ERROR("halQueueDeQueue error, queue id:[%u], ret=[%d]", relationEventQId, ret);
     480            1 :             break;
     481              :         }
     482            3 :         dequeue = true;
     483            3 :         StatisticManager::GetInstance().RelationDequeueStat();
     484              : 
     485            3 :         ret = halMbufFree(mbufPtr);
     486            3 :         if (ret != DRV_ERROR_NONE) {
     487            1 :             BQS_LOG_ERROR("halMbufFree error, queue id:[%u], ret=[%d]", relationEventQId, ret);
     488              :         }
     489              :     }
     490              : 
     491            6 :     if (dequeue) {
     492              :         // pipeline queue id is valid : event mode
     493            3 :         if (RouterServer::GetInstance().GetPipelineQueueId() < MAX_QUEUE_ID_NUM) {
     494            0 :             RouterServer::GetInstance().BindMsgProc(index);
     495              :         } else {
     496            3 :             BqsServer::GetInstance().BindMsgProc();
     497              :         }
     498            3 :         BQS_LOG_INFO("HandleRelationEvent end.");
     499              :     }
     500            6 :     return dequeue;
     501              : }
     502              : 
     503            4 : void QueueManager::MakeUpMbuf(Mbuf** mbufPtr) const
     504              : {
     505              :     // malloc mbuf for f2nf queue
     506            4 :     const size_t mbufLen = sizeof(EntityInfo);
     507            4 :     auto drvRet = halMbufAlloc(mbufLen, mbufPtr);
     508            4 :     if (drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) {
     509            1 :         BQS_LOG_ERROR("Failed to malloc mbuf, ret=[%d]", drvRet);
     510            1 :         return;
     511              :     }
     512            3 :     Mbuf*& mbuf = *mbufPtr;
     513            3 :     drvRet = halMbufSetDataLen(mbuf, mbufLen);
     514            3 :     if (drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) {
     515            1 :         BQS_LOG_ERROR("Set data len for mbuf failed, dataLen:[%zu], ret=[%d]", mbufLen, drvRet);
     516            1 :         (void)halMbufFree(mbuf);
     517            1 :         mbuf = nullptr;
     518            1 :         return;
     519              :     }
     520              : }
     521              : 
     522            5 : void QueueManager::MakeUpF2NFMbuf(const uint32_t index)
     523              : {
     524            5 :     if (index == 0U) {
     525              :         static std::once_flag onceFlag;
     526            4 :         std::call_once(onceFlag, [&]() {
     527            1 :             BQS_LOG_INFO("make up mbufForF2nf_");
     528            1 :             MakeUpMbuf(&mbufForF2nf_);
     529            1 :         });
     530              :     } else {
     531              :         static std::once_flag onceFlagExtra;
     532            1 :         std::call_once(onceFlagExtra, [&]() {
     533            1 :             BQS_LOG_INFO("make up mbufForF2nfExtra_");
     534            1 :             MakeUpMbuf(&mbufForF2nfExtra_);
     535            1 :         });
     536              :     }
     537            5 : }
     538              : /**
     539              :  * enqueue the queue id of full to not full queue
     540              :  * @return BQS_STATUS_OK:success other:failed
     541              :  */
     542            5 : BqsStatus QueueManager::EnqueueFullToNotFullEvent(const uint32_t index)
     543              : {
     544            5 :     MakeUpF2NFMbuf(index);
     545            5 :     auto& f2nfLock = (index == 0U) ? f2nfLock_ : f2nfLockExtra_;
     546            5 :     auto& mbufForF2nf = (index == 0U) ? mbufForF2nf_ : mbufForF2nfExtra_;
     547            5 :     auto& f2nfQueueEmptyFlag = (index == 0U) ? f2nfQueueEmptyFlag_ : f2nfQueueEmptyFlagExtra_;
     548            5 :     auto& deviceId = (index == 0U) ? deviceId_ : deviceIdExtra_;
     549            5 :     auto& fullToNotFullEventQId = (index == 0U) ? fullToNotFullEventQId_ : fullToNotFullEventQIdExtra_;
     550              : 
     551            5 :     if (mbufForF2nf == nullptr) {
     552            2 :         BQS_LOG_ERROR("Failed to malloc mbuf for f2nf event, index is %u.", index);
     553            2 :         return BqsStatus::BQS_STATUS_INNER_ERROR;
     554              :     }
     555              : 
     556            3 :     f2nfLock.Lock();
     557            3 :     if (!f2nfQueueEmptyFlag.load()) {
     558            1 :         DGW_LOG_DEBUG("EnqueueFullToNotFullEvent f2NfQueueEmptyFlag is false, index is %u.", index);
     559            1 :         f2nfLock.Unlock();
     560            1 :         return BqsStatus::BQS_STATUS_OK;
     561              :     }
     562            2 :     BQS_LOG_INFO("Begin to enqueue f2nf event, index is %u.", index);
     563              :     // In order to prevent event from being dropped, first store f2nFQueueEmptyFlag to false, then enqueue
     564            2 :     f2nfQueueEmptyFlag.store(false);
     565            2 :     const auto ret = halQueueEnQueue(deviceId, fullToNotFullEventQId, mbufForF2nf);
     566            2 :     if (ret != DRV_ERROR_NONE) {
     567              :         // reset f2nfQueueEmptyFlag, perhaps events were dropped because enqueue failed
     568            1 :         f2nfQueueEmptyFlag.store(true);
     569            1 :         BQS_LOG_ERROR("halQueueEnQueue error, ret=[%d], index is %u.", ret, index);
     570            1 :         f2nfLock.Unlock();
     571            1 :         return BqsStatus::BQS_STATUS_DRIVER_ERROR;
     572              :     }
     573            1 :     f2nfLock.Unlock();
     574            1 :     StatisticManager::GetInstance().F2nfEnqueueStat();
     575            1 :     BQS_LOG_INFO("Finish to enqueue f2nf event, index is %u,", index);
     576            1 :     return BqsStatus::BQS_STATUS_OK;
     577              : }
     578              : 
     579              : /**
     580              :  * handle the event of full to not full
     581              :  * @return true:has handle f2nf msg, false:not handle
     582              :  */
     583            6 : bool QueueManager::HandleFullToNotFullEvent(const uint32_t index)
     584              : {
     585            6 :     uint32_t dequeueCount = 0U;
     586            6 :     auto& f2nfLock = (index == 0U) ? f2nfLock_ : f2nfLockExtra_;
     587            6 :     auto& mbufForF2nf = (index == 0U) ? mbufForF2nf_ : mbufForF2nfExtra_;
     588            6 :     auto& f2nfQueueEmptyFlag = (index == 0U) ? f2nfQueueEmptyFlag_ : f2nfQueueEmptyFlagExtra_;
     589            6 :     auto& deviceId = (index == 0U) ? deviceId_ : deviceIdExtra_;
     590            6 :     auto& fullToNotFullEventQId = (index == 0U) ? fullToNotFullEventQId_ : fullToNotFullEventQIdExtra_;
     591              : 
     592            6 :     f2nfLock.Lock();
     593           10 :     while (dequeueCount <= MAX_DEQUEUE_COUNT) {
     594           10 :         void* dequeuedMbuf = nullptr;
     595           10 :         const int32_t ret = halQueueDeQueue(deviceId, fullToNotFullEventQId, &dequeuedMbuf);
     596           10 :         if (ret == DRV_ERROR_QUEUE_EMPTY) {
     597            5 :             break;
     598              :         }
     599            5 :         if (ret != DRV_ERROR_NONE) {
     600            1 :             BQS_LOG_ERROR("halQueueDeQueue error, queue id:[%u], ret=[%d]", fullToNotFullEventQId, ret);
     601            1 :             f2nfLock.Unlock();
     602            1 :             return false;
     603              :         }
     604            4 :         mbufForF2nf = PtrToPtr<void, Mbuf>(dequeuedMbuf);
     605            4 :         StatisticManager::GetInstance().F2nfDequeueStat();
     606              :         // mbuf for f2nf event will be freed when destroy queue manager
     607            4 :         dequeueCount++;
     608              :     }
     609            5 :     f2nfQueueEmptyFlag.store(true);
     610            5 :     f2nfLock.Unlock();
     611            5 :     return (dequeueCount > 0U);
     612              : }
     613              : 
     614              : /**
     615              :  * Enqueue a data to implies that the clientQ sent a message
     616              :  * @return BQS_STATUS_OK:success other:failed
     617              :  */
     618            5 : BqsStatus QueueManager::EnqueueAsynMemBuffEvent()
     619              : {
     620              :     // avoid parallel halEnQueue
     621            5 :     std::lock_guard<std::mutex> lock(mutex_);
     622            5 :     Mbuf* mbufPtr = nullptr;
     623            5 :     int32_t ret = halMbufAlloc(BIND_EVENT_MSG_LENGTH, &mbufPtr);
     624            5 :     if (ret != DRV_ERROR_NONE) {
     625            1 :         BQS_LOG_ERROR(
     626              :             "halMbufAlloc error, queue id:[%u]/[%u], ret=[%d]", asyncMemDequeueBuffQId_, asyncMemEnqueueBuffQId_, ret);
     627            1 :         return BQS_STATUS_DRIVER_ERROR;
     628              :     }
     629              : 
     630            4 :     uint32_t asyncMemBuffQId = 0;
     631            4 :     if (isTriggeredByAsyncMemDequeue_) {
     632            2 :         asyncMemBuffQId = asyncMemDequeueBuffQId_;
     633            2 :         ret = halQueueEnQueue(deviceId_, asyncMemDequeueBuffQId_, mbufPtr);
     634            2 :     } else if (isTriggeredByAsyncMemEnqueue_) {
     635            2 :         asyncMemBuffQId = asyncMemEnqueueBuffQId_;
     636            2 :         ret = halQueueEnQueue(deviceId_, asyncMemEnqueueBuffQId_, mbufPtr);
     637              :     } else {
     638              :         ;
     639              :     }
     640              : 
     641            4 :     if (ret != DRV_ERROR_NONE) {
     642            2 :         BQS_LOG_ERROR("halQueueEnQueue error, queue id:[%u], ret=[%d]", asyncMemBuffQId, ret);
     643            2 :         (void)halMbufFree(mbufPtr);
     644            2 :         return BQS_STATUS_DRIVER_ERROR;
     645              :     }
     646            2 :     StatisticManager::GetInstance().AsynMemEnqueueStat();
     647            2 :     return BQS_STATUS_OK;
     648            5 : }
     649              : 
     650              : /**
     651              :  * handle the event of Aysn mem buffer
     652              :  * @return true:has handle Aysn mem buffer msg, false:not handle
     653              :  */
     654            5 : bool QueueManager::HandleAsynMemBuffEvent(const uint32_t index)
     655              : {
     656              :     (void)index;
     657            5 :     Mbuf* mbufPtr = nullptr;
     658            5 :     int32_t ret = DRV_ERROR_RESERVED;
     659            5 :     bool isTriggered = false;
     660              :     while (true) {
     661            6 :         uint32_t asyncMemBuffQId = 0;
     662            6 :         if (isTriggeredByAsyncMemDequeue_) {
     663            5 :             isTriggered = true;
     664            5 :             asyncMemBuffQId = asyncMemDequeueBuffQId_;
     665            5 :             ret = halQueueDeQueue(deviceId_, asyncMemDequeueBuffQId_, PtrToPtr<Mbuf*, void*>(&mbufPtr));
     666              :         }
     667              : 
     668            6 :         if (isTriggeredByAsyncMemEnqueue_) {
     669            5 :             isTriggered = true;
     670            5 :             asyncMemBuffQId = asyncMemEnqueueBuffQId_;
     671            5 :             ret = halQueueDeQueue(deviceId_, asyncMemEnqueueBuffQId_, PtrToPtr<Mbuf*, void*>(&mbufPtr));
     672              :         }
     673              : 
     674            6 :         if (ret == DRV_ERROR_QUEUE_EMPTY || ret == DRV_ERROR_RESERVED) {
     675            2 :             if (isTriggeredByAsyncMemDequeue_) {
     676            1 :                 isTriggeredByAsyncMemDequeue_ = false;
     677              :             }
     678            2 :             if (isTriggeredByAsyncMemEnqueue_) {
     679            1 :                 isTriggeredByAsyncMemEnqueue_ = false;
     680              :             }
     681            2 :             break;
     682              :         }
     683              : 
     684            4 :         if (ret != DRV_ERROR_NONE) {
     685            3 :             BQS_LOG_ERROR("halQueueDeQueue error, queue id:[%u], ret=[%d]", asyncMemBuffQId, ret);
     686            3 :             break;
     687              :         }
     688              : 
     689            1 :         if (isTriggered) {
     690            1 :             StatisticManager::GetInstance().AsynMemDequeueStat();
     691            1 :             ret = halMbufFree(mbufPtr);
     692            1 :             if (ret != DRV_ERROR_NONE) {
     693            1 :                 BQS_LOG_ERROR("halMbufFree error, queue id:[%u], ret=[%d]", asyncMemBuffQId, ret);
     694              :             }
     695              :         }
     696            1 :     }
     697            5 :     return true;
     698              : }
     699              : 
     700            1 : void QueueManager::LogErrorRelationQueueStatus() const { LogErrorQueueStatus(relationEventQId_); }
     701              : 
     702            1 : void QueueManager::LogErrorQueueStatus(const uint32_t queueId) const
     703              : {
     704              :     QueueInfo queueInfoObj;
     705            1 :     auto ret = halQueueQueryInfo(deviceId_, queueId, &queueInfoObj);
     706            1 :     if (ret == DRV_ERROR_NONE) {
     707            1 :         BQS_LOG_ERROR(
     708              :             "halQueueQueryInfo get queue info, deviceId_:%u, "
     709              :             "queueId:%u, size:%d, depth:%d, status:%d, workMode:%d, "
     710              :             "type:%d, subGroupId:%d,subPid:%d, subF2NFGroupId:%d, "
     711              :             "subF2NFPid:%d, enqueCnt:%llu, dequeCnt:%llu, "
     712              :             "enqueFailCnt:%llu, dequeFailCnt:%llu, enqueEventOk:%llu, "
     713              :             "enqueEventFail:%llu, f2nfEventOk:%llu, f2nfEventFail:%llu, "
     714              :             "lastEnqueTime.tv_sec:%ld, lastEnqueTime.tv_usec:%ld, "
     715              :             "lastDequeTime.tv_sec:%ld, lastDequeTime.tv_usec:%ld.",
     716              :             deviceId_, queueInfoObj.id, queueInfoObj.size, queueInfoObj.depth, queueInfoObj.status,
     717              :             queueInfoObj.workMode, queueInfoObj.type, queueInfoObj.subGroupId, queueInfoObj.subPid,
     718              :             queueInfoObj.subF2NFGroupId, queueInfoObj.subF2NFPid, queueInfoObj.stat.enqueCnt,
     719              :             queueInfoObj.stat.dequeCnt, queueInfoObj.stat.enqueFailCnt, queueInfoObj.stat.dequeFailCnt,
     720              :             queueInfoObj.stat.enqueEventOk, queueInfoObj.stat.enqueEventFail, queueInfoObj.stat.f2nfEventOk,
     721              :             queueInfoObj.stat.f2nfEventFail, queueInfoObj.stat.lastEnqueTime.tv_sec,
     722              :             queueInfoObj.stat.lastEnqueTime.tv_usec, queueInfoObj.stat.lastDequeTime.tv_sec,
     723              :             queueInfoObj.stat.lastDequeTime.tv_usec);
     724              :     } else {
     725            0 :         BQS_LOG_ERROR("halQueueQueryInfo error, deviceId_:[%u], queueId:[%u], ret:[%d]", deviceId_, queueId, ret);
     726              :     }
     727              : 
     728            1 :     int32_t status = QUEUE_NORMAL;
     729            1 :     ret = halQueueGetStatus(deviceId_, queueId, QUERY_QUEUE_STATUS, static_cast<uint32_t>(sizeof(uint32_t)), &status);
     730            1 :     if (ret == DRV_ERROR_NONE) {
     731            1 :         BQS_LOG_DEBUG("halQueueGetStatus succ, queueId:[%u] status:[%d].", queueId, status);
     732              :     } else {
     733            0 :         BQS_LOG_ERROR("halQueueGetStatus failed, queueId:[%u], ret:[%d].", queueId, ret);
     734              :     }
     735            1 : }
     736              : } // namespace bqs
        

Generated by: LCOV version 2.0-1