Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
memory_pool.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
7/*
8 * Simple fixed-block memory pool (prototype)
9 * Not wired into container_system by default; intended for experimentation.
10 */
11
12#include <cstddef>
13#include <cstdint>
14#include <vector>
15#include <mutex>
16#include <memory>
17#include <stdexcept>
18
20
22public:
23 explicit fixed_block_pool(std::size_t block_size,
24 std::size_t blocks_per_chunk = 1024)
25 : block_size_(block_size < sizeof(void*) ? sizeof(void*) : block_size)
26 , blocks_per_chunk_(blocks_per_chunk) {}
27
28 ~fixed_block_pool() = default;
29
30 void* allocate() {
31 std::lock_guard<std::mutex> lock(mutex_);
32 if (!free_list_) {
33 try {
35 } catch (const std::bad_alloc&) {
36 // Chunk allocation failed, propagate the exception
37 throw;
38 }
39 // Verify that allocate_chunk_unlocked() actually created free blocks
40 if (!free_list_) {
41 throw std::runtime_error("Memory pool chunk allocation failed to create free list");
42 }
43 }
44 void* p = free_list_;
45 free_list_ = *reinterpret_cast<void**>(free_list_);
47 return p;
48 }
49
50 void deallocate(void* p) {
51 if (!p) return;
52 std::lock_guard<std::mutex> lock(mutex_);
53
54 // Validate pointer belongs to one of our pool chunks.
55 // This lightweight range check runs in all build modes to
56 // prevent free-list corruption from invalid deallocations.
57 bool found = false;
58 for (const auto& chunk : chunks_) {
59 std::uint8_t* chunk_start = chunk.get();
60 std::uint8_t* chunk_end = chunk_start + (block_size_ * blocks_per_chunk_);
61 if (reinterpret_cast<std::uint8_t*>(p) >= chunk_start &&
62 reinterpret_cast<std::uint8_t*>(p) < chunk_end) {
63 found = true;
64 break;
65 }
66 }
67 if (!found) {
68 return;
69 }
70
71 *reinterpret_cast<void**>(p) = free_list_;
72 free_list_ = p;
74 }
75
76 std::size_t block_size() const noexcept { return block_size_; }
77
81 struct statistics {
82 std::size_t total_chunks; // Number of chunks allocated
83 std::size_t allocated_blocks; // Number of blocks currently in use
84 std::size_t total_capacity; // Total number of blocks across all chunks
85 std::size_t free_blocks; // Number of blocks in free list
86
87 // Calculated metrics
88 double utilization_ratio() const {
89 return total_capacity > 0
90 ? static_cast<double>(allocated_blocks) / total_capacity
91 : 0.0;
92 }
93
94 std::size_t memory_bytes() const {
95 // This would need block_size, which we don't have in this struct
96 // For now, just return 0; caller can calculate if needed
97 return 0;
98 }
99 };
100
106 std::lock_guard<std::mutex> lock(mutex_);
107
108 // Count free blocks in the free list
109 std::size_t free_count = 0;
110 void* current = free_list_;
111 while (current) {
112 ++free_count;
113 current = *reinterpret_cast<void**>(current);
114 }
115
116 std::size_t total_capacity = chunks_.size() * blocks_per_chunk_;
117
118 return statistics{
119 chunks_.size(),
121 total_capacity,
122 free_count
123 };
124 }
125
126private:
128 std::unique_ptr<std::uint8_t[]> chunk(new std::uint8_t[block_size_ * blocks_per_chunk_]);
129 std::uint8_t* base = chunk.get();
130 chunks_.push_back(std::move(chunk));
131 // Build free list
132 for (std::size_t i = 0; i < blocks_per_chunk_; ++i) {
133 void* p = base + i * block_size_;
134 *reinterpret_cast<void**>(p) = free_list_;
135 free_list_ = p;
136 }
137 }
138
139private:
140 std::size_t block_size_;
141 std::size_t blocks_per_chunk_;
142 std::vector<std::unique_ptr<std::uint8_t[]>> chunks_;
143 void* free_list_{nullptr};
144 mutable std::mutex mutex_; // Mutable to allow locking in const methods
145 std::size_t allocated_count_{0}; // Track number of currently allocated blocks
146};
147
148} // namespace kcenon::container::internal
149
fixed_block_pool(std::size_t block_size, std::size_t blocks_per_chunk=1024)
Definition memory_pool.h:23
statistics get_statistics() const
Get current pool statistics.
std::size_t block_size() const noexcept
Definition memory_pool.h:76
std::vector< std::unique_ptr< std::uint8_t[]> > chunks_
Statistics for monitoring memory pool usage.
Definition memory_pool.h:81