blob: 06a9218dcc888df456b0641670d24d98f4a03eba (
plain) (
blame)
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
|
#include "precomp_wasabi_bfc.h"
#include "freelist.h"
// define this to turn off freelist behavior
//#define FREELIST_FUCT
FreelistPriv::FreelistPriv() {
total_allocated = 0;
}
FreelistPriv::~FreelistPriv() {
#ifdef ASSERTS_ENABLED
// ASSERTPR(total_allocated == 0, "didn't free entire freelist!(1)");
// ASSERTPR(blocks.getNumItems() == 0, "didn't free entire freelist!(2)");
if (total_allocated != 0) DebugStringW(L"didn't free entire freelist!(1)\n");
if (blocks.getNumItems() != 0) DebugStringW(L"didn't free entire freelist!(2)\n");
#endif
}
void *FreelistPriv::getRecord(int typesize, int blocksize, int initialblocksize) {
#ifdef FREELIST_FUCT
return MALLOC(typesize);
#else
ASSERT(typesize >= sizeof(void *));
FLMemBlock *mem = NULL;
for (int i = 0; i < blocks.getNumItems(); i++) {
mem = blocks[i];
if (mem->freelist != NULL) break;
mem = NULL;
}
if (mem == NULL) {
// figure record count for this new block
int siz = (blocks.getNumItems() ? blocksize : initialblocksize);
// allocate another block of memory
mem = new FLMemBlock(siz*typesize);
// prelink it into a freelist
char *record = static_cast<char *>(mem->freelist);
void **ptr;
for (int i = 0; i < siz-1; i++) {
ptr = reinterpret_cast<void **>(record);
record += typesize;
*ptr = static_cast<void *>(record);
}
// terminate newly made freelist
ptr = reinterpret_cast<void **>(record);
*ptr = NULL;
blocks.addItem(mem);
}
// get first free record
void *ret = mem->freelist;
// advance freelist *
mem->freelist = *(static_cast<void **>(mem->freelist));
mem->nallocated++;
total_allocated++;
return ret;
#endif
}
void FreelistPriv::freeRecord(void *record) {
#ifdef FREELIST_FUCT
FREE(record);
#else
FLMemBlock *mem=NULL;
for (int i = 0; i < blocks.getNumItems(); i++) {
mem = blocks[i];
if (mem->isMine(reinterpret_cast<MBT*>(record))) break;
mem = NULL;
}
ASSERTPR(mem != NULL, "attempted to free record with no block");
// stash it back on the block's freelist
*reinterpret_cast<void **>(record) = mem->freelist;
mem->freelist = record;
ASSERT(mem->nallocated > 0);
mem->nallocated--;
if (mem->nallocated == 0) {
blocks.delItem(mem);
}
total_allocated--;
#endif
}
|