-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathFixsizeAllocator.cpp
97 lines (95 loc) · 2.16 KB
/
FixsizeAllocator.cpp
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
#include "pch.h"
#include "FixsizeAllocator.h"
class SizeNAllocator
{
public:
SizeNAllocator(int entrySize, int blockSize);
~SizeNAllocator();
void* alloc();
void free(void *p);
private:
void allocBlock();
private:
struct Entry
{
Entry *next;
char data[1];
};
private:
int m_blockSize, m_entrySize;
Entry *m_freeList;
vector<void*> m_blocks;
};
SizeNAllocator::SizeNAllocator(int entrySize, int blockSize):
m_freeList(NULL), m_blockSize(blockSize), m_entrySize(entrySize)
{
}
SizeNAllocator::~SizeNAllocator()
{
for (auto &p : m_blocks) ::free(p);
}
void* SizeNAllocator::alloc()
{
if (m_freeList == NULL) allocBlock();
void *r = m_freeList;
m_freeList = m_freeList->next;
return r;
}
void SizeNAllocator::free(void *p)
{
Entry *entry = (Entry*)p;
entry->next = m_freeList;
m_freeList = entry;
}
void SizeNAllocator::allocBlock()
{
assert(m_entrySize >= 4);
Entry *block = (Entry*)::malloc(m_blockSize * m_entrySize);
Entry *ent = block;
for (int i = 0; i < m_blockSize - 1; ++i) {
Entry *nextEnt = (Entry*)((char*)ent + m_entrySize);
ent->next = nextEnt;
ent = nextEnt;
}
ent->next = m_freeList;
m_freeList = block;
m_blocks.push_back(block);
}
FixsizeAllocator::FixsizeAllocator()
{
int sa[] = {4,8,16,24,32,40,48,64,80,96,128};
for (auto sz : sa) {
m_sizeNs.push_back(sz);
m_sizeNAllocators.push_back(new SizeNAllocator(sz, (1<<20)/sz));
}
}
FixsizeAllocator::~FixsizeAllocator()
{
for (auto &p : m_sizeNAllocators) delete p;
}
void* FixsizeAllocator::malloc(int size)
{
size += 1;
auto iter = lower_bound(m_sizeNs.begin(), m_sizeNs.end(), size);
if (iter == m_sizeNs.end()) {
char *p = (char*)::malloc(size);
p[0] = -1;
return p + 1;
}
else {
int idx = int(iter - m_sizeNs.begin());
char *p = (char*)m_sizeNAllocators[idx]->alloc();
p[0] = idx;
return p + 1;
}
}
void FixsizeAllocator::free(void *_p)
{
char *p = (char*)_p;
if (p[-1] == -1) {
::free(p - 1);
}
else {
m_sizeNAllocators[p[-1]]->free(p - 1);
}
}