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,
64 : rest), HCCL_E_MEMORY);
65 0 : sRet = memcpy_s(data_, count - rest, src + rest, count - rest);
66 0 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet,
67 : count - rest), HCCL_E_MEMORY);
68 : }
69 2 : size_ += count;
70 2 : tail_ = (tail_ + count) % capacity_;
71 :
72 2 : return HCCL_SUCCESS;
73 : }
74 1 : HcclResult PopSeg(u32 count)
75 : {
76 1 : if (size_ < count) {
77 0 : HCCL_ERROR("[RingBuffer] Not Enough Element");
78 0 : return HCCL_E_PARA;
79 : }
80 1 : size_ -= count;
81 1 : head_ = (head_ + count) % capacity_;
82 :
83 1 : return HCCL_SUCCESS;
84 : }
85 1 : HcclResult GetSeg(u8* dst, u32 count) const
86 : {
87 1 : CHK_PTR_NULL(dst);
88 1 : if (size_ < count) {
89 0 : HCCL_ERROR("[RingBuffer] Not Enough Element");
90 0 : return HCCL_E_PARA;
91 : }
92 :
93 1 : u32 rest = capacity_ - head_;
94 : // 如果队头到右边界的元素足够出队,则直接出队
95 : // 否则,从队头出rest个元素后,再从左边界出队
96 1 : if (rest >= count) {
97 1 : s32 sRet = memcpy_s(dst, count, data_ + head_, count);
98 1 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet,
99 : count), HCCL_E_MEMORY);
100 : } else {
101 0 : s32 sRet = memcpy_s(dst, rest, data_ + head_, rest);
102 0 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet,
103 : rest), HCCL_E_MEMORY);
104 0 : sRet = memcpy_s(dst + rest, count - rest, data_, count - rest);
105 0 : CHK_PRT_RET(sRet != EOK, HCCL_ERROR("memcpy_s failed, errorno[%d], size[%u]", sRet,
106 : count - rest), HCCL_E_MEMORY);
107 : }
108 :
109 1 : return HCCL_SUCCESS;
110 : }
111 4 : u32 Size() const
112 : {
113 4 : return size_;
114 : }
115 : private:
116 : u32 capacity_ = 0;
117 : u32 head_ = 0;
118 : u32 tail_ = 0;
119 : u32 size_ = 0;
120 : u8* data_ = nullptr;
121 : bool initialized_ = false;
122 : };
123 :
124 : } // namespace hccl
125 : #endif // HCCL_RINGBUFFER_H
|