-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMemoryPool.cpp
108 lines (95 loc) · 3.31 KB
/
MemoryPool.cpp
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
#ifndef MEMORY_POOL_HPP
#define MEMORY_POOL_HPP
#include <climits>
#include <cstddef>
template <typename T, size_t BlockSize = 4096>
class MemoryPool
{
public:
// 使用 typedef 简化类型书写
typedef T* pointer;
// 定义 rebind<U>::other 接口
template <typename U> struct rebind {
typedef MemoryPool<U> other;
};
// 默认构造
// C++11 使用了 noexcept 来显式的声明此函数不会抛出异常
MemoryPool() noexcept {
currentBlock_ = nullptr;
currentSlot_ = nullptr;
lastSlot_ = nullptr;
freeSlots_ = nullptr;
}
// 销毁一个现有的内存池
~MemoryPool() noexcept {
// 循环销毁内存池中分配的内存区块
slot_pointer_ curr = currentBlock_;
while (curr != nullptr) {
slot_pointer_ prev = curr->next;
operator delete(reinterpret_cast<void*>(curr));
curr = prev;
}
}
// 同一时间只能分配一个对象, n 和 hint 会被忽略
pointer allocate(size_t n = 1, const T* hint = 0) {
if (freeSlots_ != nullptr) {
pointer result = reinterpret_cast<pointer>(freeSlots_);
freeSlots_ = freeSlots_->next;
return result;
}
else {
if (currentSlot_ >= lastSlot_) {
// 分配一个内存区块
data_pointer_ newBlock = reinterpret_cast<data_pointer_>(operator new(BlockSize));
reinterpret_cast<slot_pointer_>(newBlock)->next = currentBlock_;
currentBlock_ = reinterpret_cast<slot_pointer_>(newBlock);
data_pointer_ body = newBlock + sizeof(slot_pointer_);
uintptr_t result = reinterpret_cast<uintptr_t>(body);
size_t bodyPadding = (alignof(slot_type_) - result) % alignof(slot_type_);
currentSlot_ = reinterpret_cast<slot_pointer_>(body + bodyPadding);
lastSlot_ = reinterpret_cast<slot_pointer_>(newBlock + BlockSize - sizeof(slot_type_));
}
return reinterpret_cast<pointer>(currentSlot_++);
}
}
// 销毁指针 p 指向的内存区块
void deallocate(pointer p, size_t n = 1) {
if (p != nullptr) {
reinterpret_cast<slot_pointer_>(p)->next = freeSlots_;
freeSlots_ = reinterpret_cast<slot_pointer_>(p);
}
}
// 调用构造函数, 使用 std::forward 转发变参模板
template <typename U, typename... Args>
void construct(U* p, Args&&... args) {
new (p) U (std::forward<Args>(args)...);
}
// 销毁内存池中的对象, 即调用对象的析构函数
template <typename U>
void destroy(U* p) {
p->~U();
}
private:
// 用于存储内存池中的对象槽
union Slot_ {
T element;
Slot_* next;
};
// 数据指针
typedef char* data_pointer_;
// 对象槽
typedef Slot_ slot_type_;
// 对象槽指针
typedef Slot_* slot_pointer_;
// 指向当前内存区块
slot_pointer_ currentBlock_;
// 指向当前内存区块的一个对象槽
slot_pointer_ currentSlot_;
// 指向当前内存区块的最后一个对象槽
slot_pointer_ lastSlot_;
// 指向当前内存区块中的空闲对象槽
slot_pointer_ freeSlots_;
// 检查定义的内存池大小是否过小
static_assert(BlockSize >= 2 * sizeof(slot_type_), "BlockSize too small.");
};
#endif // MEMORY_POOL_HPP