blob: dba7e46e24ba5f1f5339370b92389a39b8d0545a (
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
82
83
84
85
86
87
88
89
90
91
92
93
|
#ifndef _FREELIST_H
#define _FREELIST_H
#include <bfc/wasabi_std.h>
#include <bfc/memblock.h>
#include <bfc/ptrlist.h>
// actual implementation
class FreelistPriv {
protected:
FreelistPriv();
~FreelistPriv();
void *getRecord(int typesize, int blocksize, int initialblocksize);
void freeRecord(void *rec);
private:
int total_allocated;
typedef uint8_t MBT;
class FLMemBlock : public MemBlock<MBT> {
public:
FLMemBlock(int siz) : MemBlock<MBT>(siz) {
freelist = getMemory();
nallocated = 0;
}
void *freelist;
int nallocated; // # of records assigned from block
};
PtrList< FLMemBlock > blocks; // the blocks of mem we alloc from
};
// type-safe template
static const int DEF_BLOCKSIZE=250;
template
<class T, int BLOCKSIZE=DEF_BLOCKSIZE, int INITIALBLOCKSIZE=DEF_BLOCKSIZE, int ALIGNMENT=4>
class Freelist : private FreelistPriv {
public:
// just returns the memory, you have to call constructor manually
T *getRecord() {
return static_cast<T *>(FreelistPriv::getRecord(itemsize(), BLOCKSIZE, INITIALBLOCKSIZE));
}
// creates object via default constructor
T *newRecord() {
T *ret = getRecord();
#ifdef FORTIFY
#undef new
#endif
new(ret) T;
#ifdef FORTIFY
#define new ZFortify_New
#endif
return ret;
}
// creates object via 1-parameter constructor
template<class P1>
T *newRecord(P1 p1) {
T *ret = getRecord();
#ifdef FORTIFY
#undef new
#endif
new(ret) T(p1);
#ifdef FORTIFY
#define new ZFortify_New
#endif
return ret;
}
// just frees it, you have to call destructor manually
void freeRecord(T *record) { FreelistPriv::freeRecord(record); }
// calls delete for you, and frees it
void deleteRecord(T *record) {
if (record != NULL) {
record->~T();
freeRecord(record);
}
}
void deletePtrList(PtrList<T> *list) {
ASSERT(list != NULL);
for (int i = 0; i < list->getNumItems(); i++) {
deleteRecord(list->enumItem(i));
}
list->removeAll();
}
protected:
int itemsize() { return (sizeof(T) + (ALIGNMENT-1)) - (sizeof(T) % ALIGNMENT); }
};
#endif
|