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

Generated by: LCOV version 2.0-1