yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory_pool.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdlib>
5#include <cstring>
6
7namespace yaze {
8namespace gfx {
9
11
13 static MemoryPool instance;
14 return instance;
15}
16
18 : total_allocations_(0), total_deallocations_(0),
19 total_used_bytes_(0), total_allocated_bytes_(0) {
20 // Initialize block pools with common graphics sizes
21 InitializeBlockPool(small_blocks_, kSmallBlockSize, 100); // 100KB for small tiles
22 InitializeBlockPool(medium_blocks_, kMediumBlockSize, 50); // 200KB for medium tiles
23 InitializeBlockPool(large_blocks_, kLargeBlockSize, 20); // 320KB for large tiles
24 InitializeBlockPool(huge_blocks_, kHugeBlockSize, 10); // 640KB for graphics sheets
25
27 (20 * kLargeBlockSize) + (10 * kHugeBlockSize);
28}
29
33
34void* MemoryPool::Allocate(size_t size) {
36
37 MemoryBlock* block = FindFreeBlock(size);
38 if (!block) {
39 // Fallback to system malloc if no pool block available
40 void* data = std::malloc(size);
41 if (data) {
42 total_used_bytes_ += size;
43 allocated_blocks_[data] = nullptr; // Mark as system allocated
44 }
45 return data;
46 }
47
48 block->in_use = true;
49 total_used_bytes_ += block->size;
50 allocated_blocks_[block->data] = block;
51
52 return block->data;
53}
54
55void MemoryPool::Deallocate(void* ptr) {
56 if (!ptr) return;
57
59
60 auto it = allocated_blocks_.find(ptr);
61 if (it == allocated_blocks_.end()) {
62 // System allocated, use free
63 std::free(ptr);
64 return;
65 }
66
67 MemoryBlock* block = it->second;
68 if (block) {
69 block->in_use = false;
70 total_used_bytes_ -= block->size;
71 }
72
73 allocated_blocks_.erase(it);
74}
75
76void* MemoryPool::AllocateAligned(size_t size, size_t alignment) {
77 // For simplicity, allocate extra space and align manually
78 // In a production system, you'd want more sophisticated alignment handling
79 size_t aligned_size = size + alignment - 1;
80 void* ptr = Allocate(aligned_size);
81
82 if (ptr) {
83 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
84 uintptr_t aligned_addr = (addr + alignment - 1) & ~(alignment - 1);
85 return reinterpret_cast<void*>(aligned_addr);
86 }
87
88 return nullptr;
89}
90
91std::pair<size_t, size_t> MemoryPool::GetMemoryStats() const {
93}
94
95std::pair<size_t, size_t> MemoryPool::GetAllocationStats() const {
97}
98
100 // Reset all blocks to unused state
101 for (auto& block : small_blocks_) {
102 block.in_use = false;
103 }
104 for (auto& block : medium_blocks_) {
105 block.in_use = false;
106 }
107 for (auto& block : large_blocks_) {
108 block.in_use = false;
109 }
110 for (auto& block : huge_blocks_) {
111 block.in_use = false;
112 }
113
114 allocated_blocks_.clear();
116}
117
119 // Determine which pool to use based on size
120 size_t pool_index = GetPoolIndex(size);
121
122 std::vector<MemoryBlock>* pools[] = {
124 };
125
126 if (pool_index >= 4) {
127 return nullptr; // Size too large for any pool
128 }
129
130 auto& pool = *pools[pool_index];
131
132 // Find first unused block
133 auto it = std::find_if(pool.begin(), pool.end(),
134 [](const MemoryBlock& block) { return !block.in_use; });
135
136 return (it != pool.end()) ? &(*it) : nullptr;
137}
138
139void MemoryPool::InitializeBlockPool(std::vector<MemoryBlock>& pool,
140 size_t block_size, size_t count) {
141 pool.reserve(count);
142
143 for (size_t i = 0; i < count; ++i) {
144 void* data = std::malloc(block_size);
145 if (data) {
146 pool.emplace_back(data, block_size);
147 }
148 }
149}
150
151size_t MemoryPool::GetPoolIndex(size_t size) const {
152 if (size <= kSmallBlockSize) return 0;
153 if (size <= kMediumBlockSize) return 1;
154 if (size <= kLargeBlockSize) return 2;
155 if (size <= kHugeBlockSize) return 3;
156 return 4; // Too large for any pool
157}
158
159} // namespace gfx
160} // namespace yaze
High-performance memory pool allocator for graphics data.
Definition memory_pool.h:38
static constexpr size_t kSmallBlockSize
Definition memory_pool.h:95
void Deallocate(void *ptr)
Deallocate memory block.
size_t GetPoolIndex(size_t size) const
static constexpr size_t kHugeBlockSize
void * Allocate(size_t size)
Allocate memory block of specified size.
void * AllocateAligned(size_t size, size_t alignment)
Allocate memory block aligned to specified boundary.
static constexpr size_t kLargeBlockSize
Definition memory_pool.h:98
std::vector< MemoryBlock > medium_blocks_
static constexpr size_t kMediumBlockSize
Definition memory_pool.h:96
std::unordered_map< void *, MemoryBlock * > allocated_blocks_
std::vector< MemoryBlock > huge_blocks_
std::vector< MemoryBlock > small_blocks_
MemoryBlock * FindFreeBlock(size_t size)
void Clear()
Clear all allocated blocks (for cleanup)
std::pair< size_t, size_t > GetAllocationStats() const
Get allocation statistics.
std::pair< size_t, size_t > GetMemoryStats() const
Get memory usage statistics.
static MemoryPool & Get()
void InitializeBlockPool(std::vector< MemoryBlock > &pool, size_t block_size, size_t count)
std::vector< MemoryBlock > large_blocks_
Main namespace for the application.