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 HCCL_RINGBUFFER_H
12 : #define HCCL_RINGBUFFER_H
13 :
14 : #include "hccl/hccl_types.h"
15 : #include "log.h"
16 :
17 : namespace hccl {
18 :
19 : class RingBuffer {
20 : public:
21 25 : RingBuffer() {}
22 76 : ~RingBuffer()
23 : {
24 76 : if (capacity_ > 0 && data_ != nullptr) {
25 3 : delete[] data_;
26 3 : data_ = nullptr;
27 3 : capacity_ = 0;
28 : }
29 76 : }
30 3 : HcclResult Init(u32 capacity)
31 : {
32 3 : if (initialized_) {
33 0 : return HCCL_SUCCESS;
34 : }
35 3 : capacity_ = capacity;
36 3 : if (capacity_ <= 0) {
37 0 : HCCL_ERROR("[RingBuffer] capacity[%u] must greater than 0", capacity_);
38 0 : return HCCL_E_PARA;
39 : }
40 :
41 3 : data_ = new (std::nothrow) u8[capacity_];
42 3 : CHK_PTR_NULL(data_);
43 3 : initialized_ = true;
44 :
45 3 : return HCCL_SUCCESS;
46 : }
47 2 : HcclResult PushSeg(u8* src, u32 count)
48 : {
49 2 : CHK_PTR_NULL(src);
50 2 : if (size_ > capacity_ || count > (capacity_ - size_)) {
51 0 : HCCL_ERROR("[RingBuffer] Not Enough Space");
52 0 : return HCCL_E_PARA;
53 : }
54 :
55 2 : u32 rest = capacity_ - tail_;
56 : // 如果队尾到右边界的空间足够入队,则直接入队
57 : // 否则,从队尾入rest个元素后,再从左边界入队
58 2 : if (rest >= count) {
59 2 : s32 sRet = memcpy_s(data_ + tail_, count, src, count);
60 2 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, count), HCCL_E_MEMORY);
61 : } else {
62 0 : s32 sRet = memcpy_s(data_ + tail_, rest, src, rest);
63 0 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, rest), HCCL_E_MEMORY);
64 0 : sRet = memcpy_s(data_, count - rest, src + rest, count - rest);
65 0 : CHK_PRT_RET(
66 : sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, count - rest), HCCL_E_MEMORY);
67 : }
68 2 : size_ += count;
69 2 : tail_ = (tail_ + count) % capacity_;
70 :
71 2 : return HCCL_SUCCESS;
72 : }
73 1 : HcclResult PopSeg(u32 count)
74 : {
75 1 : if (size_ < count) {
76 0 : HCCL_ERROR("[RingBuffer] Not Enough Element");
77 0 : return HCCL_E_PARA;
78 : }
79 1 : size_ -= count;
80 1 : head_ = (head_ + count) % capacity_;
81 :
82 1 : return HCCL_SUCCESS;
83 : }
84 1 : HcclResult GetSeg(u8* dst, u32 count) const
85 : {
86 1 : CHK_PTR_NULL(dst);
87 1 : if (size_ < count) {
88 0 : HCCL_ERROR("[RingBuffer] Not Enough Element");
89 0 : return HCCL_E_PARA;
90 : }
91 :
92 1 : u32 rest = capacity_ - head_;
93 : // 如果队头到右边界的元素足够出队,则直接出队
94 : // 否则,从队头出rest个元素后,再从左边界出队
95 1 : if (rest >= count) {
96 1 : s32 sRet = memcpy_s(dst, count, data_ + head_, count);
97 1 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, count), HCCL_E_MEMORY);
98 : } else {
99 0 : s32 sRet = memcpy_s(dst, rest, data_ + head_, rest);
100 0 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, rest), HCCL_E_MEMORY);
101 0 : sRet = memcpy_s(dst + rest, count - rest, data_, count - rest);
102 0 : CHK_PRT_RET(
103 : sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet, count - rest), HCCL_E_MEMORY);
104 : }
105 :
106 1 : return HCCL_SUCCESS;
107 : }
108 4 : u32 Size() const { return size_; }
109 :
110 : private:
111 : u32 capacity_ = 0;
112 : u32 head_ = 0;
113 : u32 tail_ = 0;
114 : u32 size_ = 0;
115 : u8* data_ = nullptr;
116 : bool initialized_ = false;
117 : };
118 :
119 : } // namespace hccl
120 : #endif // HCCL_RINGBUFFER_H
|