HAllocator
A Simple C++ Memory Allocator
Loading...
Searching...
No Matches
BlocksContainer.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#include <cstddef>
13#include <limits>
14#include <utility>
15
16#include "Block.hpp"
17
18namespace hh::halloc {
19
35template <std::size_t BlockSize, int MaxNumBlocks>
37 Block blocks[MaxNumBlocks];
38 int current_block_index;
39
57 std::pair<std::size_t, MemoryNode*> best_fit(std::size_t bytes);
58
59public:
65
84 void* allocate(std::size_t bytes);
85
102 void deallocate(void* ptr, std::size_t bytes);
103
109 void log_container_state(std::ofstream& logfile) const;
110};
111} // namespace hh::halloc
112
113namespace hh::halloc {
123inline std::size_t get_actual_value(std::size_t value) {
124 return value & ~(3ull << 62);
125}
126
147template <std::size_t BlockSize, int MaxNumBlocks>
148std::pair<std::size_t, MemoryNode*> BlocksContainer<BlockSize, MaxNumBlocks>::best_fit(
149 std::size_t bytes) {
150 std::size_t best_block_index = std::numeric_limits<std::size_t>::max();
151 std::size_t best_size = std::numeric_limits<std::size_t>::max();
152 MemoryNode* best_node = nullptr;
153
154 // Search all initialized blocks
155 for (int i = 0; i <= current_block_index; i++) {
156 MemoryNode* node = blocks[i].best_fit(bytes);
157 if (node) {
158 std::size_t node_size = get_actual_value(node->value);
159 // Track smallest fit
160 if (node_size < best_size) {
161 best_node = node;
162 best_size = node_size;
163 best_block_index = i;
164 }
165 }
166 }
167
168 return {best_block_index, best_node};
169}
170
182template <std::size_t BlockSize, int MaxNumBlocks>
184 current_block_index = 0;
185 blocks[current_block_index] = std::move(Block(BlockSize));
186}
187
209template <std::size_t BlockSize, int MaxNumBlocks>
211 if (bytes < 1) {
212 throw std::invalid_argument("Bytes must be positive");
213 }
214
215 auto [index, node] = best_fit(bytes);
216
217 // No suitable node found in existing blocks
218 if (index == std::numeric_limits<std::size_t>::max()) {
219 // Try to create a new block
220 if (current_block_index + 1 < MaxNumBlocks) {
221 current_block_index++;
222 blocks[current_block_index] = std::move(Block(BlockSize));
223 index = current_block_index;
224 node = blocks[index].best_fit(bytes);
225 }
226 }
227
234 if (!node) {
235 return REQUEST_MEMORY_VIA_MMAP(bytes);
236 }
237
238 // Allocate from the selected block
239 return blocks[index].allocate(bytes, node);
240}
241
263template <std::size_t BlockSize, int MaxNumBlocks>
265 // Find which block owns this pointer
266 for (int i = 0; i <= current_block_index; i++) {
267 // Check if ptr is within block i's address range
268 void* block_start = blocks[i].get_head();
269 void* block_end = (char*)block_start + BlockSize;
270
271 if (block_start <= ptr && ptr < block_end) {
272 blocks[i].deallocate(ptr, bytes);
273 return;
274 }
275 }
276
281 RELEASE_MEMORY_VIA_MUNMAP(ptr, bytes);
282}
283
284template <std::size_t BlockSize, int MaxNumBlocks>
286 logfile << "=================================================\n";
287 logfile << "BlocksContainer State:\n";
288 logfile << "Total Blocks: " << (current_block_index + 1) << "\n";
289 for (int i = 0; i <= current_block_index; i++) {
290 logfile << "---------------- Block " << i << " ----------------\n";
291 blocks[i].log_block_state(logfile);
292 logfile << "---------------- End Block " << i << " ----------------\n";
293 }
294 logfile << "=================================================\n\n";
295}
296}; // namespace hh::halloc
Memory block management with Red-Black tree based allocator.
#define RELEASE_MEMORY_VIA_MUNMAP(ptr, size)
Releases memory back to the operating system using munmap.
Definition Block.hpp:33
#define REQUEST_MEMORY_VIA_MMAP(size)
Allocates memory from the operating system using mmap.
Definition Block.hpp:24
Manages a contiguous memory block with RB-tree based allocation.
Definition Block.hpp:86
Manages multiple memory blocks for scalable allocation.
Definition BlocksContainer.hpp:36
BlocksContainer()
Default constructor - initializes container with no blocks.
Definition BlocksContainer.hpp:183
void deallocate(void *ptr, std::size_t bytes)
Deallocates previously allocated memory.
Definition BlocksContainer.hpp:264
void log_container_state(std::ofstream &logfile) const
Logs the current state of the container to a file.
Definition BlocksContainer.hpp:285
void * allocate(std::size_t bytes)
Allocates memory from the container.
Definition BlocksContainer.hpp:210
Definition Block.hpp:35
std::size_t get_actual_value(std::size_t value)
Helper function to extract actual size from encoded value.
Definition BlocksContainer.hpp:123