Quake II RTX doxygen
1.0 dev
zone.c
Go to the documentation of this file.
1
/*
2
Copyright (C) 1997-2001 Id Software, Inc.
3
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License along
15
with this program; if not, write to the Free Software Foundation, Inc.,
16
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
*/
18
19
#include "shared/shared.h"
20
#include "common/common.h"
21
#include "common/zone.h"
22
23
#define Z_MAGIC 0x1d0d
24
#define Z_TAIL 0x5b7b
25
26
#define Z_TAIL_F(z) \
27
*(uint16_t *)((byte *)(z) + (z)->size - sizeof(uint16_t))
28
29
#define Z_FOR_EACH(z) \
30
for ((z) = z_chain.next; (z) != &z_chain; (z) = (z)->next)
31
32
#define Z_FOR_EACH_SAFE(z, n) \
33
for ((z) = z_chain.next; (z) != &z_chain; (z) = (n))
34
35
typedef
struct
zhead_s
{
36
uint16_t
magic
;
37
uint16_t
tag
;
// for group free
38
size_t
size
;
39
#ifdef _DEBUG
40
void
*addr;
41
time_t time;
42
#endif
43
struct
zhead_s
*
prev
, *
next
;
44
}
zhead_t
;
45
46
// number of overhead bytes
47
#define Z_EXTRA (sizeof(zhead_t) + sizeof(uint16_t))
48
49
static
zhead_t
z_chain
;
50
51
typedef
struct
{
52
zhead_t
z
;
53
char
data[2];
54
uint16_t
tail
;
55
}
zstatic_t
;
56
57
static
const
zstatic_t
z_static
[] = {
58
#define Z_STATIC(x) \
59
{ { Z_MAGIC, TAG_STATIC, q_offsetof(zstatic_t, tail) + sizeof(uint16_t) }, x, Z_TAIL }
60
61
Z_STATIC
(
"0"
),
62
Z_STATIC
(
"1"
),
63
Z_STATIC
(
"2"
),
64
Z_STATIC
(
"3"
),
65
Z_STATIC
(
"4"
),
66
Z_STATIC
(
"5"
),
67
Z_STATIC
(
"6"
),
68
Z_STATIC
(
"7"
),
69
Z_STATIC
(
"8"
),
70
Z_STATIC
(
"9"
),
71
Z_STATIC
(
""
)
72
73
#undef Z_STATIC
74
};
75
76
typedef
struct
{
77
size_t
count
;
78
size_t
bytes
;
79
}
zstats_t
;
80
81
static
zstats_t
z_stats
[TAG_MAX];
82
83
static
const
char
z_tagnames
[TAG_MAX][8] = {
84
"game"
,
85
"static"
,
86
"generic"
,
87
"cmd"
,
88
"cvar"
,
89
"fs"
,
90
"refresh"
,
91
"ui"
,
92
"server"
,
93
"mvd"
,
94
"sound"
,
95
"cmodel"
96
};
97
98
static
inline
void
Z_Validate
(
zhead_t
*z,
const
char
*func)
99
{
100
if
(z->
magic
!=
Z_MAGIC
) {
101
Com_Error
(ERR_FATAL,
"%s: bad magic"
, func);
102
}
103
if
(
Z_TAIL_F
(z) !=
Z_TAIL
) {
104
Com_Error
(ERR_FATAL,
"%s: bad tail"
, func);
105
}
106
if
(z->
tag
== TAG_FREE) {
107
Com_Error
(ERR_FATAL,
"%s: bad tag"
, func);
108
}
109
}
110
111
void
Z_Check
(
void
)
112
{
113
zhead_t
*z;
114
115
Z_FOR_EACH
(z) {
116
Z_Validate
(z, __func__);
117
}
118
}
119
120
void
Z_LeakTest
(memtag_t tag)
121
{
122
zhead_t
*z;
123
size_t
numLeaks = 0, numBytes = 0;
124
125
Z_FOR_EACH
(z) {
126
Z_Validate
(z, __func__);
127
if
(z->
tag
== tag) {
128
numLeaks++;
129
numBytes += z->
size
;
130
}
131
}
132
133
if
(numLeaks) {
134
Com_WPrintf(
"************* Z_LeakTest *************\n"
135
"%s leaked %"
PRIz
" bytes of memory (%"
PRIz
" object%s)\n"
136
"**************************************\n"
,
137
z_tagnames
[tag < TAG_MAX ? tag : TAG_FREE],
138
numBytes, numLeaks, numLeaks == 1 ?
""
:
"s"
);
139
}
140
}
141
142
/*
143
========================
144
Z_Free
145
========================
146
*/
147
void
Z_Free
(
void
*ptr)
148
{
149
zhead_t
*z;
150
zstats_t
*s;
151
152
if
(!ptr) {
153
return
;
154
}
155
156
z = (
zhead_t
*)ptr - 1;
157
158
Z_Validate
(z, __func__);
159
160
s = &
z_stats
[z->
tag
< TAG_MAX ? z->
tag
: TAG_FREE];
161
s->
count
--;
162
s->
bytes
-= z->
size
;
163
164
if
(z->
tag
!= TAG_STATIC) {
165
z->
prev
->
next
= z->
next
;
166
z->
next
->
prev
= z->
prev
;
167
z->
magic
= 0xdead;
168
z->
tag
= TAG_FREE;
169
free(z);
170
}
171
}
172
173
/*
174
========================
175
Z_Realloc
176
========================
177
*/
178
void
*
Z_Realloc
(
void
*ptr,
size_t
size)
179
{
180
zhead_t
*z;
181
zstats_t
*s;
182
183
if
(!ptr) {
184
return
Z_Malloc(size);
185
}
186
187
if
(!size) {
188
Z_Free
(ptr);
189
return
NULL;
190
}
191
192
z = (
zhead_t
*)ptr - 1;
193
194
Z_Validate
(z, __func__);
195
196
if
(z->
tag
== TAG_STATIC) {
197
Com_Error
(ERR_FATAL,
"%s: couldn't realloc static memory"
, __func__);
198
}
199
200
s = &
z_stats
[z->
tag
< TAG_MAX ? z->
tag
: TAG_FREE];
201
s->
bytes
-= z->
size
;
202
203
if
(size > SIZE_MAX -
Z_EXTRA
- 3) {
204
Com_Error
(ERR_FATAL,
"%s: bad size"
, __func__);
205
}
206
207
size = (size +
Z_EXTRA
+ 3) & ~3;
208
z = realloc(z, size);
209
if
(!z) {
210
Com_Error
(ERR_FATAL,
"%s: couldn't realloc %"
PRIz
" bytes"
, __func__, size);
211
}
212
213
z->
size
= size;
214
z->
prev
->
next
= z;
215
z->
next
->
prev
= z;
216
217
s->
bytes
+= size;
218
219
Z_TAIL_F
(z) =
Z_TAIL
;
220
221
return
z + 1;
222
}
223
224
/*
225
========================
226
Z_Stats_f
227
========================
228
*/
229
void
Z_Stats_f
(
void
)
230
{
231
size_t
bytes = 0, count = 0;
232
zstats_t
*s;
233
int
i;
234
235
Com_Printf(
" bytes blocks name\n"
236
"--------- ------ -------\n"
);
237
238
for
(i = 0, s =
z_stats
; i < TAG_MAX; i++, s++) {
239
if
(!s->
count
) {
240
continue
;
241
}
242
Com_Printf(
"%9"
PRIz
" %6"
PRIz
" %s\n"
, s->
bytes
, s->
count
,
z_tagnames
[i]);
243
bytes += s->
bytes
;
244
count += s->
count
;
245
}
246
247
Com_Printf(
"--------- ------ -------\n"
248
"%9"
PRIz
" %6"
PRIz
" total\n"
,
249
bytes, count);
250
}
251
252
/*
253
========================
254
Z_FreeTags
255
========================
256
*/
257
void
Z_FreeTags
(memtag_t tag)
258
{
259
zhead_t
*z, *n;
260
261
Z_FOR_EACH_SAFE
(z, n) {
262
Z_Validate
(z, __func__);
263
n = z->
next
;
264
if
(z->
tag
== tag) {
265
Z_Free
(z + 1);
266
}
267
}
268
}
269
270
/*
271
========================
272
Z_TagMalloc
273
========================
274
*/
275
void
*
Z_TagMalloc
(
size_t
size, memtag_t tag)
276
{
277
zhead_t
*z;
278
zstats_t
*s;
279
280
if
(!size) {
281
return
NULL;
282
}
283
284
if
(tag == TAG_FREE) {
285
Com_Error
(ERR_FATAL,
"%s: bad tag"
, __func__);
286
}
287
288
if
(size > SIZE_MAX -
Z_EXTRA
- 3) {
289
Com_Error
(ERR_FATAL,
"%s: bad size"
, __func__);
290
}
291
292
size = (size +
Z_EXTRA
+ 3) & ~3;
293
z = malloc(size);
294
if
(!z) {
295
Com_Error
(ERR_FATAL,
"%s: couldn't allocate %"
PRIz
" bytes"
, __func__, size);
296
}
297
z->
magic
=
Z_MAGIC
;
298
z->
tag
= tag;
299
z->
size
= size;
300
301
#ifdef _DEBUG
302
#if (defined __GNUC__)
303
z->addr = __builtin_return_address(0);
304
#elif (defined _MSC_VER)
305
z->addr = _ReturnAddress();
306
#else
307
z->addr = NULL;
308
#endif
309
z->time = time(NULL);
310
#endif
311
312
z->
next
=
z_chain
.
next
;
313
z->
prev
= &
z_chain
;
314
z_chain
.
next
->
prev
= z;
315
z_chain
.
next
= z;
316
317
if
(
z_perturb
&&
z_perturb
->integer) {
318
memset(z + 1,
z_perturb
->integer, size -
Z_EXTRA
);
319
}
320
321
Z_TAIL_F
(z) =
Z_TAIL
;
322
323
s = &
z_stats
[tag < TAG_MAX ? tag : TAG_FREE];
324
s->
count
++;
325
s->
bytes
+= size;
326
327
return
z + 1;
328
}
329
330
void
*
Z_TagMallocz
(
size_t
size, memtag_t tag)
331
{
332
if
(!size) {
333
return
NULL;
334
}
335
return
memset(
Z_TagMalloc
(size, tag), 0, size);
336
}
337
338
static
byte
*
z_reserved_data
;
339
static
size_t
z_reserved_inuse
;
340
static
size_t
z_reserved_total
;
341
342
void
Z_TagReserve
(
size_t
size, memtag_t tag)
343
{
344
z_reserved_data
=
Z_TagMalloc
(size, tag);
345
z_reserved_total
= size;
346
z_reserved_inuse
= 0;
347
}
348
349
void
*
Z_ReservedAlloc
(
size_t
size)
350
{
351
void
*ptr;
352
353
if
(!size) {
354
return
NULL;
355
}
356
357
if
(size >
z_reserved_total
-
z_reserved_inuse
) {
358
Com_Error
(ERR_FATAL,
"%s: couldn't allocate %"
PRIz
" bytes"
, __func__, size);
359
}
360
361
ptr =
z_reserved_data
+
z_reserved_inuse
;
362
z_reserved_inuse
+= size;
363
364
return
ptr;
365
}
366
367
void
*
Z_ReservedAllocz
(
size_t
size)
368
{
369
if
(!size) {
370
return
NULL;
371
}
372
return
memset(
Z_ReservedAlloc
(size), 0, size);
373
}
374
375
char
*
Z_ReservedCopyString
(
const
char
*in)
376
{
377
size_t
len;
378
379
if
(!in) {
380
return
NULL;
381
}
382
383
len = strlen(in) + 1;
384
return
memcpy(
Z_ReservedAlloc
(len), in, len);
385
}
386
387
/*
388
========================
389
Z_Init
390
========================
391
*/
392
void
Z_Init
(
void
)
393
{
394
z_chain
.
next
=
z_chain
.
prev
= &
z_chain
;
395
}
396
397
/*
398
================
399
Z_TagCopyString
400
================
401
*/
402
char
*
Z_TagCopyString
(
const
char
*in, memtag_t tag)
403
{
404
size_t
len;
405
406
if
(!in) {
407
return
NULL;
408
}
409
410
len = strlen(in) + 1;
411
return
memcpy(
Z_TagMalloc
(len, tag), in, len);
412
}
413
414
/*
415
================
416
Z_CvarCopyString
417
================
418
*/
419
char
*
Z_CvarCopyString
(
const
char
*in)
420
{
421
size_t
len;
422
zstatic_t
*z;
423
zstats_t
*s;
424
int
i;
425
426
if
(!in) {
427
return
NULL;
428
}
429
430
if
(!in[0]) {
431
i = 10;
432
}
else
if
(!in[1] && Q_isdigit(in[0])) {
433
i = in[0] -
'0'
;
434
}
else
{
435
len = strlen(in) + 1;
436
return
memcpy(
Z_TagMalloc
(len, TAG_CVAR), in, len);
437
}
438
439
// return static storage
440
z = (
zstatic_t
*)&
z_static
[i];
441
s = &
z_stats
[TAG_STATIC];
442
s->
count
++;
443
s->
bytes
+= z->
z
.
size
;
444
return
z->
data
;
445
}
446
447
Z_ReservedAlloc
void * Z_ReservedAlloc(size_t size)
Definition:
zone.c:349
Z_CvarCopyString
char * Z_CvarCopyString(const char *in)
Definition:
zone.c:419
zstatic_t
Definition:
zone.c:51
Z_EXTRA
#define Z_EXTRA
Definition:
zone.c:47
z_reserved_total
static size_t z_reserved_total
Definition:
zone.c:340
zstats_t
Definition:
zone.c:76
Z_LeakTest
void Z_LeakTest(memtag_t tag)
Definition:
zone.c:120
Z_FOR_EACH_SAFE
#define Z_FOR_EACH_SAFE(z, n)
Definition:
zone.c:32
Z_FOR_EACH
#define Z_FOR_EACH(z)
Definition:
zone.c:29
zhead_s::prev
struct zhead_s * prev
Definition:
zone.c:43
zhead_s::magic
uint16_t magic
Definition:
zone.c:36
zstats_t::bytes
size_t bytes
Definition:
zone.c:78
zstatic_t::data
char data[2]
Definition:
zone.c:53
zstatic_t::z
zhead_t z
Definition:
zone.c:52
Z_Stats_f
void Z_Stats_f(void)
Definition:
zone.c:229
Z_MAGIC
#define Z_MAGIC
Definition:
zone.c:23
Z_TagCopyString
char * Z_TagCopyString(const char *in, memtag_t tag)
Definition:
zone.c:402
Z_TagMalloc
void * Z_TagMalloc(size_t size, memtag_t tag)
Definition:
zone.c:275
z_static
static const zstatic_t z_static[]
Definition:
zone.c:57
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition:
g_main.c:258
z_perturb
cvar_t * z_perturb
Definition:
common.c:75
Z_ReservedCopyString
char * Z_ReservedCopyString(const char *in)
Definition:
zone.c:375
zhead_s::next
struct zhead_s * next
Definition:
zone.c:43
Z_Free
void Z_Free(void *ptr)
Definition:
zone.c:147
zstats_t::count
size_t count
Definition:
zone.c:77
Z_TagMallocz
void * Z_TagMallocz(size_t size, memtag_t tag)
Definition:
zone.c:330
Z_ReservedAllocz
void * Z_ReservedAllocz(size_t size)
Definition:
zone.c:367
Z_Check
void Z_Check(void)
Definition:
zone.c:111
Z_TagReserve
void Z_TagReserve(size_t size, memtag_t tag)
Definition:
zone.c:342
zhead_s::size
size_t size
Definition:
zone.c:38
zhead_t
struct zhead_s zhead_t
z_stats
static zstats_t z_stats[TAG_MAX]
Definition:
zone.c:81
zstatic_t::tail
uint16_t tail
Definition:
zone.c:54
z_tagnames
static const char z_tagnames[TAG_MAX][8]
Definition:
zone.c:83
Z_Init
void Z_Init(void)
Definition:
zone.c:392
zhead_s::tag
uint16_t tag
Definition:
zone.c:37
z_chain
static zhead_t z_chain
Definition:
zone.c:49
Z_FreeTags
void Z_FreeTags(memtag_t tag)
Definition:
zone.c:257
Z_STATIC
#define Z_STATIC(x)
z_reserved_inuse
static size_t z_reserved_inuse
Definition:
zone.c:339
Z_Validate
static void Z_Validate(zhead_t *z, const char *func)
Definition:
zone.c:98
Z_Realloc
void * Z_Realloc(void *ptr, size_t size)
Definition:
zone.c:178
z_reserved_data
static byte * z_reserved_data
Definition:
zone.c:338
Z_TAIL
#define Z_TAIL
Definition:
zone.c:24
Z_TAIL_F
#define Z_TAIL_F(z)
Definition:
zone.c:26
zhead_s
Definition:
zone.c:35
src
common
zone.c
Generated by
1.8.17