1 #ifndef BLOCK_ALLOCATOR_H
2 #define BLOCK_ALLOCATOR_H
4 #if defined _MT || defined _REENTRANT
5 # define USE_ALLOCATOR_MUTEX
12 #ifdef EXTERNAL_DISTRO
19 template<int BLOCK_SIZE
>
28 unsigned mBuffer
[(BLOCK_SIZE
-1)/sizeof(unsigned)+1];
38 for (int block
=0; block
<MAX_BLOCK_COUNT
; block
++)
39 mMemoryBlock
[block
] = 0;
45 for (int block
=0; block
<MAX_BLOCK_COUNT
; block
++)
46 delete[] mMemoryBlock
[block
];
51 #ifdef USE_ALLOCATOR_MUTEX
56 Node
* node
= mUnusedList
;
57 mUnusedList
= node
->mNext
;
58 node
->mNext
= (Node
*)1;
64 #ifdef USE_ALLOCATOR_MUTEX
71 void Deallocate(void * data
)
76 char * memoryPtr
= reinterpret_cast<char *>(data
) - sizeof(Node
*);
77 Node
* node
= reinterpret_cast<Node
*>(memoryPtr
);
79 #ifdef USE_ALLOCATOR_MUTEX
83 node
->mNext
= mUnusedList
;
87 #ifdef USE_ALLOCATOR_MUTEX
92 template<class T
> T
* Construct(const T
& object
)
96 #ifdef USE_ALLOCATOR_MUTEX
99 if (sizeof(T
) > BLOCK_SIZE
|| (!mUnusedList
&& !Allocate()))
101 char * memoryPtr
= reinterpret_cast<char *>(new unsigned[(sizeof(Node
*)+sizeof(T
)-1)/sizeof(unsigned)+1]);
102 objectPtr
= reinterpret_cast<T
*>(memoryPtr
+sizeof(Node
*));
104 *reinterpret_cast<unsigned *>(memoryPtr
) = 0;
108 Node
* node
= mUnusedList
;
109 mUnusedList
= node
->mNext
;
110 node
->mNext
= (Node
*)1;
112 objectPtr
= reinterpret_cast<T
*>(node
->mBuffer
);
117 new (objectPtr
) T(object
);
119 #ifdef USE_ALLOCATOR_MUTEX
125 template<class T
> void Destroy(T
* object
)
130 char * memoryPtr
= reinterpret_cast<char *>(object
) - sizeof(Node
*);
131 Node
* node
= reinterpret_cast<Node
*>(memoryPtr
);
135 #ifdef USE_ALLOCATOR_MUTEX
138 if (node
->mNext
== 0)
142 node
->mNext
= mUnusedList
;
146 #ifdef USE_ALLOCATOR_MUTEX
151 template<class T
> T
* FastConstruct(const T
& object
)
155 if (sizeof(T
) > BLOCK_SIZE
|| (!mUnusedList
&& !Allocate()))
157 char * memoryPtr
= reinterpret_cast<char *>(new unsigned[(sizeof(Node
*)+sizeof(T
)-1)/sizeof(unsigned)+1]);
158 objectPtr
= reinterpret_cast<T
*>(memoryPtr
+sizeof(Node
*));
160 *reinterpret_cast<unsigned *>(memoryPtr
) = 0;
164 Node
* node
= mUnusedList
;
165 mUnusedList
= node
->mNext
;
166 node
->mNext
= (Node
*)1;
168 objectPtr
= reinterpret_cast<T
*>(node
->mBuffer
);
173 new (objectPtr
) T(object
);
178 template<class T
> void FastDestroy(T
* object
)
183 char * memoryPtr
= reinterpret_cast<char *>(object
) - sizeof(Node
*);
184 Node
* node
= reinterpret_cast<Node
*>(memoryPtr
);
188 if (node
->mNext
== 0)
192 node
->mNext
= mUnusedList
;
200 if (mMemoryBlockCount
== MAX_BLOCK_COUNT
)
203 unsigned count
= (mNodesAllocated
? mNodesAllocated
: 32);
205 Node
* newMemoryBlock
= new Node
[count
];
206 for (unsigned i
=0; i
<count
-1; i
++)
207 newMemoryBlock
[i
].mNext
= &newMemoryBlock
[i
+1];
208 newMemoryBlock
[count
-1].mNext
= mUnusedList
;
210 mUnusedList
= newMemoryBlock
;
211 mMemoryBlock
[mMemoryBlockCount
++] = newMemoryBlock
;
212 mNodesAllocated
+= count
;
218 enum { MAX_BLOCK_COUNT
= 32 };
220 void * mMemoryBlock
[MAX_BLOCK_COUNT
];
221 unsigned mMemoryBlockCount
;
222 unsigned mNodesAllocated
;
226 #ifdef USE_ALLOCATOR_MUTEX
234 #ifdef EXTERNAL_DISTRO
238 #endif // BLOCK_ALLOCATOR_H