-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmemman.cpp
More file actions
121 lines (107 loc) · 2.8 KB
/
Copy pathmemman.cpp
File metadata and controls
121 lines (107 loc) · 2.8 KB
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
/* *************************************************************************/
/*
* @file memman.cpp
* @author sean shih
* @date 09/01/2014 Mon 04:55 PM
* @brief
*
* @copyright
* All content (c) 2014-2015 DigiPen (USA) Corporation, all rights reserved.
*/
/* *************************************************************************/
#include <cstdint>
#include <cassert>
#include "memman.h"
#include "ChunkPool.h"
#pragma warning(disable:4290)
static const size_t init_offset = 2;
Memory::ChunkPool* GetChunkPools()
{
static Memory::ChunkPool chunk_pools[] =
{
#define META(chunk_size, chunk_num) Memory::ChunkPool(chunk_size, chunk_num),
#include "pool_seed.h"
#undef META
};
return chunk_pools;
}
enum Sizes
{
#define META(chunk_size, chunk_num) Size ## chunk_size = chunk_size,
#include "pool_seed.h"
#undef META
FINALSIZE_PLUS_ONE
};
static const size_t k_max_size = FINALSIZE_PLUS_ONE - 1;
static const size_t k_oversized = ~0U;
// create chunk pool list, should only be called once
static uint8_t* make_group_list()
{
enum GroupDef
{
#define META(chunk_size, chunk_num) Group ## chunk_size,
#include "pool_seed.h"
#undef META
};
static uint8_t group_list[FINALSIZE_PLUS_ONE];
for (size_t n = 0; n < FINALSIZE_PLUS_ONE; ++n)
{
if (0, false) {}
#define META(chunk_size, chunk_num) else if (n <= chunk_size) group_list[n] = Group ## chunk_size;
#include "pool_seed.h"
#undef META
else
{
assert(0 && "incorrect poool table initialization");
}
}
return group_list;
};
// find a chunkpool that allocates chunk just large enough for size
static size_t find_group(size_t size)
{
const static uint8_t* const group_list = make_group_list();
if (size > k_max_size)
return k_oversized;
else
return group_list[size];
}
// malloc from chunkpool
// when the size is larger than max chunkpool size, allocate directly
void* Memory::malloca(std::size_t size)
{
char* returned = nullptr;
if (size > 0)
{
const size_t new_group = find_group(size);
if (new_group == k_oversized)
{
returned = (char*)_aligned_malloc(size + ChunkPool::k_info_size, 16U);
returned += ChunkPool::k_info_size;
//std::printf("%u oversize, cache missed\n", size);
}
else
returned = (char*)GetChunkPools()[new_group].Alloc();
}
return returned;
}
// deallocate from chunkpool
// when the size is larger than max chunkpool size, deallocate directly
void Memory::dealloca(void* addr)
{
if (addr)
{
auto chunk_pool = Memory::ChunkPool::GetPageHeadCheck(addr);
if (chunk_pool)
chunk_pool->Dealloc(addr);
else
_aligned_free((char*)addr - Memory::ChunkPool::k_info_size);
}
}
// allocate an initialize to 0
void* Memory::calloca(std::size_t size)
{
auto returned = malloca(size);
std::memset(returned, 0, size);
return returned;
}