-
Notifications
You must be signed in to change notification settings - Fork 0
/
FastAllocator.h
181 lines (126 loc) · 4.31 KB
/
FastAllocator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once
#include <vector>
/* Fast Allocator : A custom fast Allocator efficient allocation and deallocation of memory
*/
namespace fastAllocator {
// Not yet implemented
struct FixedAllocator {
// Constructor to initialize the stuff
FixedAllocator(size_t block_sz, unsigned char num_blocks) : block_size(block_sz), numBlocks_(num_blocks), allocChunk(nullptr), dllocChunk(nullptr) {}
void* alloc() {
/* Algorithm
IF allocChunk is 0 or allocChunk->block_Available is 0
Perform a linear search in vector of chunks to find a chunk that has space
If none found create a new chunk and perform allocation
if Found then set allocChunk to current chunk and GET the pointer to the block
*/
if (allocChunk == nullptr || allocChunk->blocks_available == 0) {
for (auto chunk_el : chunks) {
if (chunk_el.blocks_available != 0) {
allocChunk = &chunk_el;
dllocChunk = &chunk_el;
return chunk_el.allocate(block_size);
}
}
// No chunks were free so add a new chunk
chunk new_chunk;
new_chunk.init(block_size, numBlocks_);
chunks.push_back(new_chunk);
allocChunk = &chunks.back();
dllocChunk = &chunks.back();
return allocChunk->allocate(block_size);
}
return allocChunk->allocate(block_size);
}
void dealloc(void * p ) {
/* Algorithm: ( There is a very high scope of optimization here )
IF p is present in dllocChunk then the block inside dllocChunk gets deallocated
ELSE
perform a linear search to find the chunk and call dealloc in it
*/
if (dllocChunk->isPresent(p, block_size * numBlocks_)) {
dllocChunk->dealloc(p, block_size);
}
for (auto chnk : chunks) {
if (chnk.isPresent(p, block_size * numBlocks_)) {
chnk.dealloc(p, block_size);
dllocChunk = &chnk;
}
}
}
private:
size_t block_size;
unsigned char numBlocks_;
struct chunk {
unsigned char* pData;
unsigned char firstAvailableBlock;
unsigned char blocks_available;
void init(size_t block_size, unsigned no_of_blocks) {
/* Algorithm
ALLOCATE pData AS new unsigned char[block_size*no_of_blocks];
SET firstAvailableBlock TO 0
SET blocks_available TO no_of_blocks
ITERATE through each block and set the first byte with index of next free block( This is freelist. It is a singly linked list where a free element
points to next element )
SET firstAvailableIndex AS *pData
*/
pData = new unsigned char[block_size * no_of_blocks];
firstAvailableBlock = 0;
blocks_available = no_of_blocks;
unsigned char* temp_ptr = pData;
for (int i = 0; i != no_of_blocks; temp_ptr += block_size) {
*temp_ptr = ++i;
}
}
void* allocate(size_t block_size) {
/* Algorithm
IF blocks ARE available
CREATE and SET pResult= pData+ (firstAvailableBlock*block_size)
SET firstAvailableBlock TO *pResult
DECREMENT blocks_available by 1
return pResult;
*/
if (blocks_available) {
unsigned char* pResult = pData + (firstAvailableBlock * block_size);
firstAvailableBlock = *pResult;
--blocks_available;
return pResult;
}
return nullptr; // No blocks to allocate
}
void dealloc(void* p, size_t block_size) {
/* Algorithm
CREATE and SET ptr= static_cast<unsigned char*> ( p);
SET *ptr AS firstAvailableBlock
SET firstAvailableBlock = static_cast<char>((ptr-pData)/block_size);
*/
if (p < pData) return; // Wrong pointer
unsigned char* release_mem = static_cast<unsigned char*>(p);
*release_mem = firstAvailableBlock;
// check Alignment
if ((release_mem - pData) % block_size != 0) return;
firstAvailableBlock = static_cast<unsigned char>((release_mem - pData) / block_size);
}
bool isPresent(void* p, size_t mem_size) {
return p > pData&& p < (pData + mem_size);
}
};
typedef std::vector<chunk> Chunks;
Chunks chunks;
chunk* allocChunk;
chunk* dllocChunk;
};
class SmallObjAllocator
{
public:
SmallObjAllocator(std::size_t chunkSize,std::size_t maxObjectSize){
while (maxObjectSize) {
}
}
void* Allocate(std::size_t numBytes);
void Deallocate(void* p, std::size_t size);
private:
std::vector<FixedAllocator> pool_;
std::size_t chunkSize_;
};
}