Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
mempool.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWLib *
24 * *
25 * $Archive:: /Commando/Code/wwlib/mempool.h $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 9/26/01 3:11p $*
30 * *
31 * $Revision:: 9 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * ObjectPoolClass::ObjectPoolClass -- constructor for ObjectPoolClass *
36 * ObjectPoolClass::~ObjectPoolClass -- destructor for ObjectPoolClass *
37 * ObjectPoolClass::Allocate_Object -- allocates an object for the user *
38 * ObjectPoolClass::Free_Object -- releases obj back into the pool *
39 * ObjectPoolClass::Allocate_Object_Memory -- internal function which returns memory for an *
40 * ObjectPoolClass::Free_Object_Memory -- internal function, returns object's memory to the *
41 * AutoPoolClass::operator new -- overriden new which calls the internal ObjectPool *
42 * AutoPoolClass::operator delete -- overriden delete which calls the internal ObjectPool *
43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45
46#if defined(_MSC_VER)
47#pragma once
48#endif
49
50#ifndef MEMPOOL_H
51#define MEMPOOL_H
52
53#include "bittype.h"
54#include "wwdebug.h"
55#include "mutex.h"
56#include <new.h>
57#include <stdlib.h>
58#include <stddef.h>
59
60
61
62/**********************************************************************************************
63** ObjectPoolClass
64**
65** This class is designed to allocate blocks of objects of type T and then dole them out
66** to you individually. The motivation for it is the situation where you are allocating
67** and freeing lots of little objects directly off the heap. Through the use of this
68** class, far fewer allocations will be actually made.
69**
70** Example Usage:
71**
72** ObjectPoolClass<ListNodeClass,256> NodePool;
73** ListNodeClass * node = NodePool.Allocate_Object();
74** NodePool.Free_Object(node);
75**
76**********************************************************************************************/
77template<class T,int BLOCK_SIZE = 64>
79{
80public:
81
84
85 T * Allocate_Object(void);
86 void Free_Object(T * obj);
87
89 void Free_Object_Memory(T * obj);
90
91protected:
92
98
99};
100
101
102
103/**********************************************************************************************
104** AutoPoolClass
105**
106** This class is designed to be derived from in order to give your class built-in
107** object pool behavior. The new and delete operators for your class will call
108** to the internal ObjectPoolClass for fast allocation and de-allocation. This
109** is very well suited to being the base class for a list node class for example.
110**
111** Notes:
112** - The array forms of new and delete are not supported
113** - You must define the instance of the static object pool (Allocator)
114** - You can't derive a class from a class that is derived from AutoPoolClass
115** because its size won't match but it will try to use the same pool...
116**
117** Example Usage:
118** --------------
119**
120** ListNode.h:
121** class ListNodeClass : public AutoPoolClass<ListNodeClass,256>
122** {
123** ListNodeClass * Next;
124** void * Data;
125** };
126**
127** ListNode.cpp:
128** DEFINE_AUTO_POOL(ListNodeClass);
129**
130** function do_stuff(void) {
131** ListNodeClass * node = new ListNodeClass;
132** delete node;
133** }
134**
135**********************************************************************************************/
136template<class T, int BLOCK_SIZE = 64>
138{
139public:
140
141 static void * operator new(size_t size);
142 static void operator delete(void * memory);
143
144private:
145
146 // not implemented
147 static void * operator new [] (size_t size);
148 static void operator delete[] (void * memory);
149
150 // This must be staticly declared by user
151 static ObjectPoolClass<T,BLOCK_SIZE> Allocator;
152
153};
154
155/*
156** DEFINE_AUTO_POOL(T,BLOCKSIZE)
157** Macro to declare the allocator for your class. Put this in the cpp file for
158** the class.
159*/
160#define DEFINE_AUTO_POOL(T,BLOCKSIZE) \
161ObjectPoolClass<T,BLOCKSIZE> AutoPoolClass<T,BLOCKSIZE>::Allocator;
162
163
164/***********************************************************************************************
165 * ObjectPoolClass::ObjectPoolClass -- constructor for ObjectPoolClass *
166 * *
167 * Initializes the object pool to the empty state *
168 * *
169 * INPUT: *
170 * *
171 * OUTPUT: *
172 * *
173 * WARNINGS: *
174 * *
175 * HISTORY: *
176 *=============================================================================================*/
177template<class T,int BLOCK_SIZE>
185
186/***********************************************************************************************
187 * ObjectPoolClass::~ObjectPoolClass -- destructor for ObjectPoolClass *
188 * *
189 * deletes the blocks of memory in use by the object pool. *
190 * *
191 * INPUT: *
192 * *
193 * OUTPUT: *
194 * *
195 * WARNINGS: *
196 * *
197 * HISTORY: *
198 *=============================================================================================*/
199template<class T,int BLOCK_SIZE>
201{
202 // assert that the user gave back all of the memory he was using
204
205 // delete all of the blocks we allocated
206 int block_count = 0;
207 while (BlockListHead != NULL) {
208 uint32 * next_block = *(uint32 **)BlockListHead;
209 ::operator delete(BlockListHead);
210 BlockListHead = next_block;
211 block_count++;
212 }
213 WWASSERT(block_count == TotalObjectCount / BLOCK_SIZE);
214}
215
216
217
218/***********************************************************************************************
219 * ObjectPoolClass::Allocate_Object -- allocates an object for the user *
220 * *
221 * If there are no free objects, another block of objects will be allocated. *
222 * *
223 * INPUT: *
224 * *
225 * OUTPUT: *
226 * *
227 * WARNINGS: *
228 * *
229 * HISTORY: *
230 * 7/29/99 GTH : Created. *
231 *=============================================================================================*/
232template<class T,int BLOCK_SIZE>
234{
235 // allocate memory for the object
236 T * obj = Allocate_Object_Memory();
237
238 // construct the object in-place
239 return new (obj) T;
240}
241
242/***********************************************************************************************
243 * ObjectPoolClass::Free_Object -- releases obj back into the pool *
244 * *
245 * INPUT: *
246 * *
247 * OUTPUT: *
248 * *
249 * WARNINGS: *
250 * *
251 * HISTORY: *
252 * 7/29/99 GTH : Created. *
253 *=============================================================================================*/
254template<class T,int BLOCK_SIZE>
256{
257 // destruct the object
258 obj->T::~T();
259
260 // release the memory
262}
263
264/***********************************************************************************************
265 * ObjectPoolClass::Allocate_Object_Memory -- internal function which returns memory for an in *
266 * *
267 * INPUT: *
268 * *
269 * OUTPUT: *
270 * *
271 * WARNINGS: *
272 * *
273 * HISTORY: *
274 * 7/29/99 GTH : Created. *
275 *=============================================================================================*/
276template<class T,int BLOCK_SIZE>
278{
280
281 if ( FreeListHead == 0 ) {
282
283 // No free objects, allocate another block
284 uint32 * tmp_block_head = BlockListHead;
285 BlockListHead = (uint32*)::operator new( sizeof(T) * BLOCK_SIZE + sizeof(uint32 *));
286 // Link this block into the block list
287 *(void **)BlockListHead = tmp_block_head;
288
289 // Link the objects in the block into the free object list
290 FreeListHead = (T*)(BlockListHead + 1);
291 for ( int i = 0; i < BLOCK_SIZE; i++ ) {
292 *(T**)(&(FreeListHead[i])) = &(FreeListHead[i+1]); // link up the elements
293 }
294 *(T**)(&(FreeListHead[BLOCK_SIZE-1])) = 0; // Mark the end
295
298 }
299
300 T * obj = FreeListHead; // Get the next free object
301 FreeListHead = *(T**)(FreeListHead); // Bump the Head
303
304 return obj;
305}
306
307
308/***********************************************************************************************
309 * ObjectPoolClass::Free_Object_Memory -- internal function, returns object's memory to the po *
310 * *
311 * INPUT: *
312 * *
313 * OUTPUT: *
314 * *
315 * WARNINGS: *
316 * *
317 * HISTORY: *
318 * 7/29/99 GTH : Created. *
319 *=============================================================================================*/
320template<class T,int BLOCK_SIZE>
322{
324
325 WWASSERT(obj != NULL);
326 *(T**)(obj) = FreeListHead; // Link to the Head
327 FreeListHead = obj; // Set the Head
329}
330
331
332/***********************************************************************************************
333 * AutoPoolClass::operator new -- overriden new which calls the internal ObjectPool *
334 * *
335 * INPUT: *
336 * *
337 * OUTPUT: *
338 * *
339 * WARNINGS: *
340 * *
341 * HISTORY: *
342 * 7/29/99 GTH : Created. *
343 *=============================================================================================*/
344template<class T, int BLOCK_SIZE>
346{
347 WWASSERT(size == sizeof(T));
348 return (void *)(Allocator.Allocate_Object_Memory());
349}
350
351
352/***********************************************************************************************
353 * AutoPoolClass::operator delete -- overriden delete which calls the internal ObjectPool *
354 * *
355 * INPUT: *
356 * *
357 * OUTPUT: *
358 * *
359 * WARNINGS: *
360 * *
361 * HISTORY: *
362 * 7/29/99 GTH : Created. *
363 *=============================================================================================*/
364template<class T, int BLOCK_SIZE>
365void AutoPoolClass<T,BLOCK_SIZE>::operator delete( void * memory )
366{
367 if ( memory == 0 ) return;
368 Allocator.Free_Object_Memory((T*)memory);
369}
370
371
372
373#endif // MEMPOOL_H
#define NULL
Definition BaseType.h:92
#define WWASSERT
unsigned long uint32
Definition bittype.h:46
#define BLOCK_SIZE
FastCriticalSectionClass ObjectPoolCS
Definition mempool.h:97
void Free_Object_Memory(T *obj)
Definition mempool.h:321
void Free_Object(T *obj)
Definition mempool.h:255
ObjectPoolClass(void)
Definition mempool.h:178
int FreeObjectCount
Definition mempool.h:95
~ObjectPoolClass(void)
Definition mempool.h:200
int TotalObjectCount
Definition mempool.h:96
T * Allocate_Object_Memory(void)
Definition mempool.h:277
T * Allocate_Object(void)
Definition mempool.h:233
uint32 * BlockListHead
Definition mempool.h:94