IRC_SERVER
By @hyunjunk (hyunjun2372@gmail.com)
Loading...
Searching...
No Matches
FlexibleFixedMemoryPool.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <cstddef>
5#include <new>
6#include <string>
7
10#include "Core/Log.hpp"
11#include "Core/MacroDefines.hpp"
12
13namespace IRCCore
14{
15
16/** A memory pool that can allocate flexible number of data
17 *
18 * @note FlexibleFixedMemoryPool Implementated using chunking with FixedMemoryPool
19 *
20 * @tparam T Type of data to allocate.
21 * @tparam MinNumDataPerChunk Minimum number of data to allocate per chunk
22 */
23template <typename T, size_t MinNumDataPerChunk = 64>
25{
26public:
28 : mChunks()
29 , mChunkCursor(0)
30 {
31 mChunks.reserve(16);
32 }
33
35 {
36 // DEBUG : Check if there is any memory leak
37 std::cout << ANSI_BBLU << "[FlexibleFixedMemoryPool] Destructor" << ANSI_RESET << std::endl;
38 for (size_t i = 0; i < mChunks.size(); ++i)
39 {
40 if (mChunks[i]->GetUsed() != 0)
41 {
42 CoreMemoryLeakLog("[FlexibleFixedMemoryPool] Memory Leak Detected. ChunkIdx: " + ValToString(i) + " Used: " + ValToString(mChunks[i]->GetUsed()));
43 }
44 }
45
46 for (size_t i = 0; i < mChunks.size(); ++i)
47 {
48 delete mChunks[i];
49 }
50 }
51
53 {
54 // Find available pool
55 for (; mChunkCursor < mChunks.size(); mChunkCursor++)
56 {
57 if (mChunks[mChunkCursor]->IsCapacityFull() == false)
58 {
59 goto ALLLOCATE_NEW_BLOCK;
60 }
61 }
62
63 // Create new pool if all pools are full
65 CoreLog("[FlexibleFixedMemoryPool] New Chunk Created. Total Chunks: " + ValToString(mChunks.size()) + " Type: " + typeid(T).name());
66
67 // ! DEBUG : Check if there too many chunks
68 if (mChunks.size() > 32)
69 {
70 CoreMemoryLog("[FlexibleFixedMemoryPool] [Warning] Too many chunks. Total Chunks: " + ValToString(mChunks.size()));
71 }
72
73 ALLLOCATE_NEW_BLOCK:
74 // CoreLog("[FlexibleFixedMemoryPool] Allocate: ChunkIdx: " + ValToString(mChunkCursor));
75 Block* block = mChunks[mChunkCursor]->Allocate();
76 Assert(block != NULL);
77 block->chunkIdx = mChunkCursor;
78 return reinterpret_cast<T*>(&block->data);
79 }
80
81 void Deallocate(T* ptr)
82 {
83 if (ptr == NULL)
84 return;
85
86 // CoreLog("[FlexibleFixedMemoryPool] Deallocate: Ptr: " + ValToString(ptr));
87 // CoreMemoryLog("[FlexibleFixedMemoryPool] Deallocate: ChunkIdx: " + ValToString(block->chunkIdx));
88 Block* block = reinterpret_cast<Block*>(reinterpret_cast<char*>(ptr) - offsetof(Block, data));
89
90 // Update the cursor to the chunk that has empty space
91 if (block->chunkIdx < mChunkCursor)
92 {
93 mChunkCursor = block->chunkIdx;
94 }
95
96 mChunks[block->chunkIdx]->Deallocate(block);
97 }
98
99private:
100 struct Block
101 {
102 public:
103 size_t chunkIdx; //< Index of the chunk that allocated this block
104 ALIGNAS(ALIGNOF(T)) char data[sizeof(T)];
105 };
106
107 enum { BLOCK_SIZE = sizeof(Block) };
108 enum { CHUNK_MEMORY_PAGE_CAPACITY = (BLOCK_SIZE * MinNumDataPerChunk + PAGE_SIZE - 1) / PAGE_SIZE }; //< Ceil to the page size
109 std::vector< FixedMemoryPool< Block, CHUNK_MEMORY_PAGE_CAPACITY >* > mChunks;
110
111 /** Index of the first chunk among the chunks with empty space */
113
114public:
116};
117
118} // namespace IRCCore
#define ANSI_BBLU
Definition AnsiColorDefines.hpp:22
#define ANSI_RESET
Definition AnsiColorDefines.hpp:5
#define NODISCARD
Definition AttributeDefines.hpp:17
#define Assert(exp)
Implemented as direct interrupt to avoid dirtying the call stack with assert function when debugging.
Definition MacroDefines.hpp:30
Memory pool that can allocate fixed amount of data.
Definition FixedMemoryPool.hpp:22
A memory pool that can allocate flexible number of data.
Definition FlexibleFixedMemoryPool.hpp:25
@ CHUNK_MEMORY_PAGE_CAPACITY
Definition FlexibleFixedMemoryPool.hpp:108
~FlexibleFixedMemoryPool()
Definition FlexibleFixedMemoryPool.hpp:34
FlexibleFixedMemoryPool()
Definition FlexibleFixedMemoryPool.hpp:27
std::vector< FixedMemoryPool< Block, CHUNK_MEMORY_PAGE_CAPACITY > * > mChunks
Definition FlexibleFixedMemoryPool.hpp:109
void Deallocate(T *ptr)
Definition FlexibleFixedMemoryPool.hpp:81
@ BLOCK_SIZE
Definition FlexibleFixedMemoryPool.hpp:107
size_t mChunkCursor
Index of the first chunk among the chunks with empty space.
Definition FlexibleFixedMemoryPool.hpp:112
T * Allocate()
Definition FlexibleFixedMemoryPool.hpp:52
Definition ControlBlock.hpp:7
@ PAGE_SIZE
Definition GlobalConstants.hpp:7
void CoreLog(const std::string &msg)
Definition Log.hpp:17
void CoreMemoryLeakLog(const std::string &msg)
Definition Log.hpp:19
void CoreMemoryLog(const std::string &msg)
Definition Log.hpp:18
std::string ValToString(const T value)
Definition Log.hpp:23
Definition FlexibleFixedMemoryPool.hpp:101
ALIGNAS(ALIGNOF(T)) char data[sizeof(T)]
size_t chunkIdx
Definition FlexibleFixedMemoryPool.hpp:103