LCOV - code coverage report
Current view: top level - server/hccl - comm_channel_queue.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.0 % 57 53
Test Date: 2026-07-28 10:54:05 Functions: 100.0 % 20 20

            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              : #ifndef COMM_CHANNEL_QUEUE_H
      12              : #define COMM_CHANNEL_QUEUE_H
      13              : 
      14              : #include <atomic>
      15              : #include <cstdint>
      16              : #include "hccl/hccl_types_in.h"
      17              : #include "driver/ascend_hal.h"
      18              : #include "fsm/state_define.h"
      19              : 
      20              : namespace dgw {
      21              : // max queue depth
      22              : constexpr uint32_t MAX_QUEUE_DEPTH = 8U * 1024U * 2U + 1U;
      23              : 
      24              : template<typename T>
      25              : class CommChannelQueue {
      26              : public:
      27              :     /**
      28              :      * @brief Construct a new Comm Channel Queue object
      29              :      * @param depth queue depth
      30              :      */
      31          112 :     explicit CommChannelQueue() : depth_(1U), head_(0U), tail_(0U), ring_(nullptr)
      32          112 :     {}
      33              : 
      34              :     /**
      35              :      * @brief Destroy the Comm Channel Queue object
      36              :      */
      37          112 :     ~CommChannelQueue()
      38              :     {
      39              :         try {
      40          112 :             Uninit();
      41            0 :         } catch(...) {
      42            0 :             BQS_LOG_ERROR("CommChannelQueue destructor exception.");
      43              :         }
      44          112 :     }
      45              : 
      46              :     CommChannelQueue(const CommChannelQueue &) = delete;
      47              :     CommChannelQueue(const CommChannelQueue &&) = delete;
      48              :     CommChannelQueue &operator = (const CommChannelQueue &) = delete;
      49              :     CommChannelQueue &operator = (CommChannelQueue &&) = delete;
      50              : 
      51              :     /**
      52              :      * @brief init queue
      53              :      * @return FSM_SUCCESS: success, other: failed
      54              :      */
      55           51 :     FsmStatus Init(const uint32_t depth)
      56              :     {
      57           51 :         if ((depth == 0U) || (depth > MAX_QUEUE_DEPTH)) {
      58            3 :             BQS_LOG_ERROR("Invalid parameter, depth:[%u].", depth);
      59            3 :             return FsmStatus::FSM_FAILED;
      60              :         }
      61           48 :         depth_ = depth;
      62              : 
      63           48 :         ring_ = new (std::nothrow) T[depth_];
      64           48 :         if (ring_ == nullptr) {
      65            0 :             BQS_LOG_ERROR("Failed to kzalloc memory for queue, depth=[%u].", depth_);
      66            0 :             return FsmStatus::FSM_FAILED;
      67              :         }
      68           48 :         BQS_LOG_DEBUG("Succes to alloc memory[%zu].", sizeof(T) * depth_);
      69              : 
      70           48 :         head_ = 0U;
      71           48 :         tail_ = 0U;
      72           48 :         BQS_LOG_DEBUG("Success to init comm channel queue, depth:[%u].", depth_);
      73           48 :         return FsmStatus::FSM_SUCCESS;
      74              :     }
      75              : 
      76              :     /**
      77              :      * @brief uninit queue
      78              :      */
      79          167 :     void Uninit()
      80              :     {
      81          167 :         if (ring_ != nullptr) {
      82           48 :             delete []ring_;
      83           48 :             ring_ = nullptr;
      84           48 :             BQS_LOG_DEBUG("Success to free memory[%zu].", sizeof(T) * depth_);
      85              :         }
      86          167 :         head_ = 0U;
      87          167 :         tail_ = 0U;
      88          167 :         depth_ = 1U;
      89          167 :         BQS_LOG_DEBUG("Success to uninit comm channel queue.");
      90          167 :     }
      91              : 
      92              :     /**
      93              :      * @brief push one element to queue
      94              :      * @param buff buff
      95              :      * @return current enqueue success count, 0 failed
      96              :      */
      97           59 :     int32_t Push(T &buff)
      98              :     {
      99          177 :         BQS_LOG_DEBUG("Push queue, head:[%u], tail:[%u], depth:[%u].",
     100              :             head_.load(), tail_.load(), depth_);
     101           59 :         if (IsFull()) {
     102            6 :             return 0;
     103              :         }
     104           53 :         ring_[tail_] = std::move(buff);
     105              :         // ++tail_ cannot be used because of time sequence problem(pop concurrently)
     106           53 :         tail_ = (tail_ + 1) % depth_;
     107           53 :         return 1;
     108              :     }
     109              : 
     110              :     /**
     111              :      * @brief get first element from queue
     112              :      * @return T* first element
     113              :      */
     114           73 :     T *Front()
     115              :     {
     116          219 :         BQS_LOG_DEBUG("Get front element from queue, head:[%u], tail:[%u], depth:[%u].",
     117              :             head_.load(), tail_.load(), depth_);
     118           73 :         if (IsEmpty()) {
     119            8 :             return nullptr;
     120              :         }
     121           65 :         return &ring_[head_];
     122              :     }
     123              : 
     124              :     /**
     125              :      * @brief pop first element from queue
     126              :      * @return current pop success count, 0 failed
     127              :      */
     128           54 :     int32_t Pop()
     129              :     {
     130          162 :         BQS_LOG_DEBUG("Pop queue, head:[%u], tail:[%u], depth:[%u].",
     131              :             head_.load(), tail_.load(), depth_);
     132           54 :         if (IsEmpty()) {
     133            1 :             return 0;
     134              :         }
     135              :         // ++head_ cannot be used because of time sequence problem(push concurrently)
     136           53 :         head_ = (head_ + 1) % depth_;
     137           53 :         return 1;
     138              :     }
     139              : 
     140              :     /**
     141              :      * @brief check queue empty
     142              :      * @return true or false
     143              :      */
     144         1226 :     bool IsEmpty() const
     145              :     {
     146         3678 :         BQS_LOG_DEBUG("Check queue empty, head:[%u], tail:[%u], depth:[%u].",
     147              :             head_.load(), tail_.load(), depth_);
     148         1226 :         return (head_ == tail_);
     149              :     }
     150              : 
     151              :     /**
     152              :      * @brief check queue full
     153              :      * @return true or false
     154              :      */
     155           83 :     bool IsFull() const
     156              :     {
     157          249 :         BQS_LOG_DEBUG("Check queue full, head:[%u], tail:[%u], depth:[%u].",
     158              :             head_.load(), tail_.load(), depth_);
     159           83 :         return (((tail_ + 1) % depth_) == head_);
     160              :     }
     161              : 
     162              :     /**
     163              :      * @brief get queue elements count
     164              :      * @return queue elements count
     165              :      */
     166           62 :     uint32_t Size() const
     167              :     {
     168           62 :         return ((tail_ - head_) + depth_) % depth_;
     169              :     }
     170              : 
     171              : private:
     172              :     // max store (depth_ - 1) elements
     173              :     uint32_t depth_;
     174              :     // head: point to where the effective memory on the ring begins
     175              :     // tail: point to the released ring position
     176              :     std::atomic<uint32_t> head_;
     177              :     std::atomic<uint32_t> tail_;
     178              :     T *ring_;
     179              : };
     180              : } // namespace dgw
     181              : #endif
        

Generated by: LCOV version 2.0-1