-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuffer_pool_example.cc
More file actions
165 lines (140 loc) · 5.22 KB
/
Copy pathbuffer_pool_example.cc
File metadata and controls
165 lines (140 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// ============================================================================
// Example: Direct BufferPool and ObjectPool usage
//
// Demonstrates: BufferPool::Instance(), Allocate(), Deallocate(),
// ClassForSize(), MakeKernelBuffer(), KernelBuf SBO/Pool/Heap
// tier selection, ObjectPool create/destroy.
// ============================================================================
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <vector>
#include <talon/async_io.hpp>
using namespace talon;
using namespace talon::task;
using namespace talon::memory;
// ============================================================================
// Demo 1: BufferPool — buffer size classes and allocation
// ============================================================================
void DemoBufferPool() {
auto& bp = BufferPool::Instance();
printf("=== BufferPool: %zu size classes ===\n", bp.kNumClasses);
// Show all size classes.
for (size_t i = 0; i < bp.kNumClasses; i++) {
size_t sz = kBufferPoolClassSizes[i];
size_t cls = BufferPool::ClassForSize(sz);
printf(" class %zu: size=%zu bytes\n", cls, sz);
}
// Allocate from each tier.
printf("\nAllocating from different tiers:\n");
for (size_t sz : {64UL, 128UL, 512UL, 4096UL, 65536UL}) {
void* p = bp.Allocate(sz);
printf(" %5zu bytes -> %p (class=%zu)\n",
sz, p, BufferPool::ClassForSize(sz));
if (p != nullptr) {
// Scribble to prove the memory is valid.
std::memset(p, 0xAB, sz);
bp.Deallocate(p, sz);
}
}
// Beyond max — returns nullptr.
void* too_big = bp.Allocate(131072);
printf(" 131072 bytes -> %p (expected: nullptr — beyond max)\n", too_big);
// Deallocate nullptr is safe.
bp.Deallocate(nullptr, 64);
printf(" Deallocate(nullptr) — safe no-op\n");
}
// ============================================================================
// Demo 2: KernelBuf — three-tier storage (SBO / Pool / Heap)
// ============================================================================
void DemoKernelBuf() {
printf("\n=== KernelBuf: three-tier storage ===\n");
// SBO tier (<= 256 bytes): zero heap allocation.
{
KernelBuf kb(256);
printf(" SBO: size=%zu, data=%p (inline storage)\n",
kb.size, static_cast<void*>(kb.Data()));
kb[0] = 'H'; kb[255] = '!';
}
// Pool tier (257-65536 bytes): BufferPool allocation.
{
KernelBuf kb(4096);
printf(" Pool: size=%zu, data=%p (BufferPool)\n",
kb.size, static_cast<void*>(kb.Data()));
kb[0] = 'P'; kb[4095] = 'Q';
}
// Heap tier (> 65536 bytes): std::vector fallback.
{
KernelBuf kb(131072);
printf(" Heap: size=%zu, data=%p (std::vector)\n",
kb.size, static_cast<void*>(kb.Data()));
}
// Resize triggers tier transition (SBO -> Pool).
{
KernelBuf kb(128);
kb[0] = 'X';
printf(" Before Resize: size=%zu\n", kb.size);
kb.Resize(4096);
printf(" After Resize: size=%zu (data preserved: '%c')\n",
kb.size, kb[0]);
}
// Move constructor: ownership transfer, no copy.
{
KernelBuf k1(1024);
k1[100] = 'M';
KernelBuf k2(std::move(k1));
printf(" Move: k2[100]='%c', k2.size=%zu, k1.size=%zu\n",
k2[100], k2.size, k1.size);
}
// MakeKernelBuffer factory.
auto ptr = MakeKernelBuffer(512);
printf(" MakeKernelBuffer: size=%zu, data=%p\n",
ptr->size, static_cast<void*>(ptr->Data()));
}
// ============================================================================
// Demo 3: ObjectPool — task object pooling
// ============================================================================
struct PoolDemo {
int id;
char label[32];
PoolDemo() : id(-1) { std::memset(label, 0, sizeof(label)); }
};
void DemoObjectPool() {
printf("\n=== ObjectPool<PoolDemo> ===\n");
ObjectPool<PoolDemo> pool(128, 32);
// Acquire objects.
std::vector<PoolDemo*> objects;
for (int i = 0; i < 10; i++) {
auto* obj = pool.Acquire();
if (obj != nullptr) {
obj->id = i;
snprintf(obj->label, sizeof(obj->label), "obj-%d", i);
objects.push_back(obj);
}
}
printf(" Acquired %zu objects\n", objects.size());
// Show approximate free count.
printf(" Approx free: %zu\n", pool.ApproximateFreeCount());
// Release all.
for (auto* obj : objects) {
pool.Release(obj);
}
// Re-acquire — should get the same objects back (pooled).
auto* a = pool.Acquire();
auto* b = pool.Acquire();
printf(" Re-acquired: a=%p b=%p (pooled)\n",
static_cast<void*>(a), static_cast<void*>(b));
pool.Release(a);
pool.Release(b);
}
// ============================================================================
int main() {
printf("Async I/O Memory Subsystem Demo\n");
printf("================================\n\n");
DemoBufferPool();
DemoKernelBuf();
DemoObjectPool();
printf("\nAll memory subsystem demos complete.\n");
return 0;
}