Skip to content

Commit 8f8e29b

Browse files
committed
[Feat] Implementation of BufferManager and KvProtocol.
1 parent 32513bf commit 8f8e29b

13 files changed

Lines changed: 1743 additions & 963 deletions

File tree

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2026 Huawei Technologies Co., Ltd. All rights reserved.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
* */
24+
#include "buffer_manager.h"
25+
#include <cstring>
26+
#include <gtest/gtest.h>
27+
#include <thread>
28+
#include <vector>
29+
30+
namespace UC::ASU {
31+
namespace {
32+
33+
class BufferManagerTest : public ::testing::Test {
34+
protected:
35+
void SetUp() override {}
36+
void TearDown() override {}
37+
};
38+
39+
TEST_F(BufferManagerTest, InitAndDestroy)
40+
{
41+
BufferManager mgr;
42+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
43+
ASSERT_TRUE(status.ok()) << status.message;
44+
mgr.Destroy();
45+
}
46+
47+
TEST_F(BufferManagerTest, InitWithZeroSlotSize)
48+
{
49+
BufferManager mgr;
50+
auto status = mgr.Init(MemoryType::HOST, 0, 100);
51+
ASSERT_FALSE(status.ok());
52+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
53+
}
54+
55+
TEST_F(BufferManagerTest, InitWithZeroSlotNum)
56+
{
57+
BufferManager mgr;
58+
auto status = mgr.Init(MemoryType::HOST, 1024, 0);
59+
ASSERT_FALSE(status.ok());
60+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
61+
}
62+
63+
TEST_F(BufferManagerTest, DoubleInit)
64+
{
65+
BufferManager mgr;
66+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
67+
ASSERT_TRUE(status.ok());
68+
status = mgr.Init(MemoryType::HOST, 1024, 100);
69+
ASSERT_FALSE(status.ok());
70+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
71+
mgr.Destroy();
72+
}
73+
74+
TEST_F(BufferManagerTest, AllocateWithoutInit)
75+
{
76+
BufferManager mgr;
77+
ScatterGatherEntry sge;
78+
auto status = mgr.Allocate(64, sge);
79+
ASSERT_FALSE(status.ok());
80+
ASSERT_EQ(status.code, StatusCode::NOT_INITIALIZED);
81+
}
82+
83+
TEST_F(BufferManagerTest, AllocateZeroSize)
84+
{
85+
BufferManager mgr;
86+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
87+
ASSERT_TRUE(status.ok());
88+
89+
ScatterGatherEntry sge;
90+
status = mgr.Allocate(0, sge);
91+
ASSERT_FALSE(status.ok());
92+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
93+
94+
mgr.Destroy();
95+
}
96+
97+
TEST_F(BufferManagerTest, AllocateExceedsSlotSize)
98+
{
99+
BufferManager mgr;
100+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
101+
ASSERT_TRUE(status.ok());
102+
103+
ScatterGatherEntry sge;
104+
status = mgr.Allocate(2048, sge);
105+
ASSERT_FALSE(status.ok());
106+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
107+
108+
mgr.Destroy();
109+
}
110+
111+
TEST_F(BufferManagerTest, SingleAllocateAndFree)
112+
{
113+
BufferManager mgr;
114+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
115+
ASSERT_TRUE(status.ok());
116+
117+
ScatterGatherEntry sge;
118+
status = mgr.Allocate(64, sge);
119+
ASSERT_TRUE(status.ok()) << status.message;
120+
ASSERT_NE(sge.addr, 0);
121+
ASSERT_EQ(sge.length, 64);
122+
ASSERT_EQ(sge.lkey, 0);
123+
124+
auto* ptr = reinterpret_cast<void*>(sge.addr);
125+
std::memset(ptr, 0xAB, 64);
126+
127+
status = mgr.Free(ptr);
128+
ASSERT_TRUE(status.ok()) << status.message;
129+
130+
mgr.Destroy();
131+
}
132+
133+
TEST_F(BufferManagerTest, MultipleAllocatesAndFrees)
134+
{
135+
BufferManager mgr;
136+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
137+
ASSERT_TRUE(status.ok());
138+
139+
constexpr int kCount = 50;
140+
std::vector<ScatterGatherEntry> sges(kCount);
141+
142+
for (int i = 0; i < kCount; ++i) {
143+
status = mgr.Allocate(128, sges[i]);
144+
ASSERT_TRUE(status.ok()) << "Failed at i=" << i << ": " << status.message;
145+
ASSERT_NE(sges[i].addr, 0);
146+
std::memset(reinterpret_cast<void*>(sges[i].addr), i, 128);
147+
}
148+
149+
for (int i = 0; i < kCount; ++i) {
150+
auto* data = reinterpret_cast<unsigned char*>(sges[i].addr);
151+
for (int j = 0; j < 128; ++j) {
152+
ASSERT_EQ(data[j], static_cast<unsigned char>(i));
153+
}
154+
}
155+
156+
for (int i = 0; i < kCount; ++i) {
157+
status = mgr.Free(reinterpret_cast<void*>(sges[i].addr));
158+
ASSERT_TRUE(status.ok()) << status.message;
159+
}
160+
161+
mgr.Destroy();
162+
}
163+
164+
TEST_F(BufferManagerTest, FreeNullPointer)
165+
{
166+
BufferManager mgr;
167+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
168+
ASSERT_TRUE(status.ok());
169+
170+
status = mgr.Free(nullptr);
171+
ASSERT_FALSE(status.ok());
172+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
173+
174+
mgr.Destroy();
175+
}
176+
177+
TEST_F(BufferManagerTest, FreeWithoutInit)
178+
{
179+
BufferManager mgr;
180+
int dummy = 0;
181+
auto status = mgr.Free(&dummy);
182+
ASSERT_FALSE(status.ok());
183+
ASSERT_EQ(status.code, StatusCode::NOT_INITIALIZED);
184+
}
185+
186+
TEST_F(BufferManagerTest, FreeOutOfRangePointer)
187+
{
188+
BufferManager mgr;
189+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
190+
ASSERT_TRUE(status.ok());
191+
192+
int dummy = 0;
193+
status = mgr.Free(&dummy);
194+
ASSERT_FALSE(status.ok());
195+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
196+
197+
mgr.Destroy();
198+
}
199+
200+
TEST_F(BufferManagerTest, FreeUnalignedPointer)
201+
{
202+
BufferManager mgr;
203+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
204+
ASSERT_TRUE(status.ok());
205+
206+
ScatterGatherEntry sge;
207+
status = mgr.Allocate(64, sge);
208+
ASSERT_TRUE(status.ok());
209+
210+
auto* ptr = reinterpret_cast<char*>(sge.addr) + 1;
211+
status = mgr.Free(ptr);
212+
ASSERT_FALSE(status.ok());
213+
ASSERT_EQ(status.code, StatusCode::INVALID_ARGUMENT);
214+
215+
mgr.Free(reinterpret_cast<void*>(sge.addr));
216+
mgr.Destroy();
217+
}
218+
219+
TEST_F(BufferManagerTest, AllocateFullSlotSize)
220+
{
221+
BufferManager mgr;
222+
auto status = mgr.Init(MemoryType::HOST, 1024, 10);
223+
ASSERT_TRUE(status.ok());
224+
225+
ScatterGatherEntry sge;
226+
status = mgr.Allocate(1024, sge);
227+
ASSERT_TRUE(status.ok()) << status.message;
228+
ASSERT_EQ(sge.length, 1024);
229+
230+
std::memset(reinterpret_cast<void*>(sge.addr), 0xFF, 1024);
231+
232+
mgr.Free(reinterpret_cast<void*>(sge.addr));
233+
mgr.Destroy();
234+
}
235+
236+
TEST_F(BufferManagerTest, ReuseAfterFree)
237+
{
238+
BufferManager mgr;
239+
auto status = mgr.Init(MemoryType::HOST, 1024, 1);
240+
ASSERT_TRUE(status.ok());
241+
242+
ScatterGatherEntry sge1;
243+
status = mgr.Allocate(64, sge1);
244+
ASSERT_TRUE(status.ok());
245+
246+
auto* ptr = reinterpret_cast<void*>(sge1.addr);
247+
mgr.Free(ptr);
248+
249+
ScatterGatherEntry sge2;
250+
status = mgr.Allocate(64, sge2);
251+
ASSERT_TRUE(status.ok());
252+
ASSERT_EQ(sge2.addr, sge1.addr);
253+
254+
mgr.Free(reinterpret_cast<void*>(sge2.addr));
255+
mgr.Destroy();
256+
}
257+
258+
TEST_F(BufferManagerTest, ConcurrentAllocateAndFree)
259+
{
260+
BufferManager mgr;
261+
auto status = mgr.Init(MemoryType::HOST, 1024, 100);
262+
ASSERT_TRUE(status.ok());
263+
264+
constexpr int kThreadCount = 4;
265+
constexpr int kOpsPerThread = 500;
266+
267+
auto worker = [&mgr](int thread_id) {
268+
for (int i = 0; i < kOpsPerThread; ++i) {
269+
ScatterGatherEntry sge;
270+
auto s = mgr.Allocate(64, sge);
271+
ASSERT_TRUE(s.ok()) << "Thread " << thread_id << " op " << i << ": " << s.message;
272+
273+
std::memset(reinterpret_cast<void*>(sge.addr), thread_id, 64);
274+
275+
s = mgr.Free(reinterpret_cast<void*>(sge.addr));
276+
ASSERT_TRUE(s.ok()) << s.message;
277+
}
278+
};
279+
280+
std::vector<std::thread> threads;
281+
for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back(worker, i); }
282+
for (auto& t : threads) { t.join(); }
283+
284+
mgr.Destroy();
285+
}
286+
287+
TEST_F(BufferManagerTest, ConcurrentStressTest)
288+
{
289+
BufferManager mgr;
290+
auto status = mgr.Init(MemoryType::HOST, 256, 16);
291+
ASSERT_TRUE(status.ok());
292+
293+
constexpr int kThreadCount = 4;
294+
constexpr int kOpsPerThread = 1000;
295+
296+
auto worker = [&mgr](int thread_id) {
297+
for (int i = 0; i < kOpsPerThread; ++i) {
298+
ScatterGatherEntry sge;
299+
auto s = mgr.Allocate(128, sge);
300+
ASSERT_TRUE(s.ok());
301+
302+
std::memset(reinterpret_cast<void*>(sge.addr), thread_id, 128);
303+
304+
for (int j = 0; j < 128; ++j) {
305+
ASSERT_EQ(reinterpret_cast<unsigned char*>(sge.addr)[j], thread_id);
306+
}
307+
308+
s = mgr.Free(reinterpret_cast<void*>(sge.addr));
309+
ASSERT_TRUE(s.ok());
310+
}
311+
};
312+
313+
std::vector<std::thread> threads;
314+
for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back(worker, i); }
315+
for (auto& t : threads) { t.join(); }
316+
317+
mgr.Destroy();
318+
}
319+
320+
} // namespace
321+
} // namespace UC::ASU

ucm/transport/kv/asu/test/case/link_proto_pack_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <cstdint>
2525
#include <cstring>
2626
#include <gtest/gtest.h>
27-
#include "link_proto.h"
27+
#include "link_protocol.h"
2828

2929
namespace UC::ASU {
3030
namespace {

0 commit comments

Comments
 (0)