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
**********************************************************************************************/
77
template
<
class
T,
int
BLOCK_SIZE = 64>
78
class
ObjectPoolClass
79
{
80
public
:
81
82
ObjectPoolClass
(
void
);
83
~ObjectPoolClass
(
void
);
84
85
T *
Allocate_Object
(
void
);
86
void
Free_Object
(T * obj);
87
88
T *
Allocate_Object_Memory
(
void
);
89
void
Free_Object_Memory
(T * obj);
90
91
protected
:
92
93
T *
FreeListHead
;
94
uint32
*
BlockListHead
;
95
int
FreeObjectCount
;
96
int
TotalObjectCount
;
97
FastCriticalSectionClass
ObjectPoolCS
;
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
**********************************************************************************************/
136
template
<
class
T,
int
BLOCK_SIZE = 64>
137
class
AutoPoolClass
138
{
139
public
:
140
141
static
void
*
operator
new
(
size_t
size);
142
static
void
operator
delete
(
void
* memory);
143
144
private
:
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) \
161
ObjectPoolClass<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
*=============================================================================================*/
177
template
<
class
T,
int
BLOCK_SIZE>
178
ObjectPoolClass<T,BLOCK_SIZE>::ObjectPoolClass
(
void
) :
179
FreeListHead
(
NULL
),
180
BlockListHead
(
NULL
),
181
FreeObjectCount
(0),
182
TotalObjectCount
(0)
183
{
184
}
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
*=============================================================================================*/
199
template
<
class
T,
int
BLOCK_SIZE>
200
ObjectPoolClass<T,BLOCK_SIZE>::~ObjectPoolClass
(
void
)
201
{
202
// assert that the user gave back all of the memory he was using
203
WWASSERT
(
FreeObjectCount
==
TotalObjectCount
);
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
*=============================================================================================*/
232
template
<
class
T,
int
BLOCK_SIZE>
233
T *
ObjectPoolClass<T,BLOCK_SIZE>::Allocate_Object
(
void
)
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
*=============================================================================================*/
254
template
<
class
T,
int
BLOCK_SIZE>
255
void
ObjectPoolClass<T,BLOCK_SIZE>::Free_Object
(T * obj)
256
{
257
// destruct the object
258
obj->T::~T();
259
260
// release the memory
261
Free_Object_Memory
(obj);
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
*=============================================================================================*/
276
template
<
class
T,
int
BLOCK_SIZE>
277
T *
ObjectPoolClass<T,BLOCK_SIZE>::Allocate_Object_Memory
(
void
)
278
{
279
FastCriticalSectionClass::LockClass
lock(
ObjectPoolCS
);
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
296
FreeObjectCount
+=
BLOCK_SIZE
;
297
TotalObjectCount
+=
BLOCK_SIZE
;
298
}
299
300
T * obj =
FreeListHead
;
// Get the next free object
301
FreeListHead
= *(T**)(
FreeListHead
);
// Bump the Head
302
FreeObjectCount
--;
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
*=============================================================================================*/
320
template
<
class
T,
int
BLOCK_SIZE>
321
void
ObjectPoolClass<T,BLOCK_SIZE>::Free_Object_Memory
(T * obj)
322
{
323
FastCriticalSectionClass::LockClass
lock(
ObjectPoolCS
);
324
325
WWASSERT
(obj !=
NULL
);
326
*(T**)(obj) =
FreeListHead
;
// Link to the Head
327
FreeListHead
= obj;
// Set the Head
328
FreeObjectCount
++;
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
*=============================================================================================*/
344
template
<
class
T,
int
BLOCK_SIZE>
345
void
*
AutoPoolClass<T,BLOCK_SIZE>::operator
new
(
size_t
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
*=============================================================================================*/
364
template
<
class
T,
int
BLOCK_SIZE>
365
void
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
NULL
#define NULL
Definition
BaseType.h:92
WWASSERT
#define WWASSERT
Definition
aabtreebuilder.cpp:68
bittype.h
uint32
unsigned long uint32
Definition
bittype.h:46
BLOCK_SIZE
#define BLOCK_SIZE
Definition
W3DSmudge.cpp:205
AutoPoolClass
Definition
mempool.h:138
FastCriticalSectionClass::LockClass
Definition
mutex.h:127
FastCriticalSectionClass
Definition
mutex.h:119
ObjectPoolClass
Definition
mempool.h:79
ObjectPoolClass::ObjectPoolCS
FastCriticalSectionClass ObjectPoolCS
Definition
mempool.h:97
ObjectPoolClass::Free_Object_Memory
void Free_Object_Memory(T *obj)
Definition
mempool.h:321
ObjectPoolClass::Free_Object
void Free_Object(T *obj)
Definition
mempool.h:255
ObjectPoolClass::ObjectPoolClass
ObjectPoolClass(void)
Definition
mempool.h:178
ObjectPoolClass::FreeListHead
T * FreeListHead
Definition
mempool.h:93
ObjectPoolClass::FreeObjectCount
int FreeObjectCount
Definition
mempool.h:95
ObjectPoolClass::~ObjectPoolClass
~ObjectPoolClass(void)
Definition
mempool.h:200
ObjectPoolClass::TotalObjectCount
int TotalObjectCount
Definition
mempool.h:96
ObjectPoolClass::Allocate_Object_Memory
T * Allocate_Object_Memory(void)
Definition
mempool.h:277
ObjectPoolClass::Allocate_Object
T * Allocate_Object(void)
Definition
mempool.h:233
ObjectPoolClass::BlockListHead
uint32 * BlockListHead
Definition
mempool.h:94
mutex.h
wwdebug.h
Code
Libraries
Source
WWVegas
WWLib
mempool.h
Generated by
1.13.2