1 |
/** |
2 |
* balloc.h: Block allocation of memory segments. |
3 |
* |
4 |
* Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team |
5 |
* Rights to this code are as documented in doc/pod/gplicense.pod. |
6 |
* |
7 |
* $Id: balloc.h,v 1.3 2007-09-05 11:23:13 pippijn Exp $ |
8 |
*/ |
9 |
|
10 |
#ifndef ERMYTH_BALLOC_H |
11 |
#define ERMYTH_BALLOC_H |
12 |
|
13 |
#include <vector> |
14 |
|
15 |
extern void (*NullDealloc)(void*); |
16 |
extern void (*NullNDealloc)(void*, size_t); |
17 |
|
18 |
template<class T, |
19 |
int NewInit = 100, // The number of elements that should be allocated |
20 |
// if we give out our last element |
21 |
void* (*Alloc) (size_t) = &::operator new, |
22 |
void (*Dealloc) (void *) = &::operator delete, |
23 |
void (*NDealloc) (void *, size_t) = NullNDealloc> |
24 |
struct balloc |
25 |
{ |
26 |
static void initialise (int chunks = 100) |
27 |
{ |
28 |
for (int i = 0; i < chunks; ++i) |
29 |
{ |
30 |
T *p = static_cast<T *> (Alloc (sizeof (T))); |
31 |
T::get_list ().push_back (p); |
32 |
} |
33 |
} |
34 |
|
35 |
static void finalise () |
36 |
{ |
37 |
typename alloc_vector::iterator first = T::get_list ().begin (); |
38 |
typename alloc_vector::iterator last = T::get_list ().end (); |
39 |
while (first != last) |
40 |
{ |
41 |
T *p = *first; |
42 |
++first; |
43 |
if (NDealloc != NullNDealloc) |
44 |
NDealloc (p, sizeof (T)); |
45 |
else |
46 |
Dealloc (p); |
47 |
} |
48 |
T::get_list ().clear (); |
49 |
} |
50 |
|
51 |
void *operator new (size_t bytes) |
52 |
{ |
53 |
// extend our memory by another set of blocks if we run out of them |
54 |
if (expect_false (T::get_list ().size () == 0)) |
55 |
T::initialise (NewInit); |
56 |
|
57 |
T *p = T::get_list ().back (); |
58 |
T::get_list ().pop_back (); |
59 |
return p; |
60 |
} |
61 |
|
62 |
void operator delete (void *p) |
63 |
{ |
64 |
// this cast is legal, because we know that p will always be of type T * |
65 |
T::get_list ().push_back (static_cast<T *> (p)); |
66 |
} |
67 |
|
68 |
protected: |
69 |
balloc () |
70 |
{ |
71 |
} |
72 |
|
73 |
virtual ~balloc () |
74 |
{ |
75 |
} |
76 |
|
77 |
private: |
78 |
typedef std::vector<T *> alloc_vector; |
79 |
|
80 |
static alloc_vector &get_list () |
81 |
{ |
82 |
static alloc_vector m_free; |
83 |
return m_free; |
84 |
} |
85 |
}; |
86 |
|
87 |
#endif |