7 #include <hicn/transport/portability/c_portability.h>
8 #include <hicn/transport/utils/singleton.h>
9 #include <hicn/transport/utils/spinlock.h>
17 template <std::
size_t SIZE = 512, std::
size_t OBJECTS = 4096>
24 for (
auto& p : p_pools_) {
29 void* allocateBlock(
size_t size = SIZE) {
34 void* p_block = pop();
36 if (TRANSPORT_EXPECT_FALSE(current_pool_index_ >= max_objects_)) {
38 p_pools_.emplace_front(
39 new typename std::aligned_storage<SIZE>::type[max_objects_]);
41 current_pool_index_ = 0;
44 auto& latest = p_pools_.front();
45 index = current_pool_index_++;
48 p_block = (
void*)&latest[index];
54 void deallocateBlock(
void* pBlock) {
62 std::size_t blockSize() {
return block_size_; }
64 uint32_t blockCount() {
return block_count_; }
66 uint32_t blocksInUse() {
return blocks_in_use_; }
68 uint32_t allocations() {
return allocations_; }
70 uint32_t deallocations() {
return deallocations_; }
76 max_objects_(OBJECTS),
78 current_pool_index_(0),
83 static_assert(SIZE >=
sizeof(
long*),
"SIZE must be at least 8 bytes");
84 p_pools_.emplace_front(
85 new typename std::aligned_storage<SIZE>::type[max_objects_]);
88 void push(
void* p_memory) {
89 Block* p_block = (Block*)p_memory;
90 p_block->p_next = p_head_;
95 Block* p_block =
nullptr;
99 p_head_ = p_head_->p_next;
102 return (
void*)p_block;
109 static std::unique_ptr<FixedBlockAllocator> instance_;
111 const std::size_t block_size_;
112 const std::size_t object_size_;
113 const std::size_t max_objects_;
116 uint32_t current_pool_index_;
117 std::list<typename std::aligned_storage<SIZE>::type*> p_pools_;
118 uint32_t block_count_;
119 uint32_t blocks_in_use_;
120 uint32_t allocations_;
121 uint32_t deallocations_;
126 template <std::
size_t A, std::
size_t B>
127 std::unique_ptr<FixedBlockAllocator<A, B>>
133 template <
typename T,
typename Pool>
140 template <
typename U,
typename P>
144 using size_type = std::size_t;
145 using difference_type = ptrdiff_t;
147 using const_pointer =
const T*;
148 using reference = T&;
149 using const_reference =
const T&;
150 using value_type = T;
153 : memory_(memory), pool_(memory_pool) {}
157 template <
typename U>
159 memory_ = other.memory_;
163 template <
typename U>
168 pointer address(reference x)
const {
return &x; }
169 const_pointer address(const_reference x)
const {
return &x; }
171 pointer allocate(size_type n, pointer hint = 0) {
172 return static_cast<pointer
>(memory_);
175 void deallocate(pointer p, size_type n) { pool_->deallocateBlock(memory_); }
177 template <
typename... Args>
178 void construct(pointer p, Args&&... args) {
179 new (
static_cast<pointer
>(p)) T(std::forward<Args>(args)...);
182 void destroy(pointer p) { p->~T(); }
189 template <
typename T,
typename U,
typename V>
190 inline bool operator==(
const STLAllocator<T, V>&,
const STLAllocator<U, V>&) {
194 template <
typename T,
typename U,
typename V>
195 inline bool operator!=(
const STLAllocator<T, V>& a,
196 const STLAllocator<U, V>& b) {