Plug the edict_leaf memory leak.

This commit is contained in:
Bill Currie 2010-12-08 09:20:43 +09:00
parent 31cf4b0d78
commit e46b52a81c
5 changed files with 88 additions and 20 deletions

View file

@ -69,6 +69,8 @@ typedef struct areanode_s {
extern areanode_t sv_areanodes[AREA_NODES];
void SV_FreeAllEdictLeafs (void);
void SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, mplane_t *planes);
void SV_ClearWorld (void);

View file

@ -1142,6 +1142,7 @@ SV_SpawnServer (const char *server)
// load progs to get entity field count
sv.max_edicts = bound (MIN_EDICTS, max_edicts->int_val, MAX_EDICTS);
SV_LoadProgs ();
SV_FreeAllEdictLeafs ();
// init the data field of the edicts
for (i = 0; i < sv.max_edicts; i++) {

View file

@ -51,24 +51,39 @@ static __attribute__ ((used)) const char rcsid[] =
#include "world.h"
#define EDICT_LEAFS 32
typedef struct edict_leaf_bucket_s {
struct edict_leaf_bucket_s *next;
edict_leaf_t edict_leafs[EDICT_LEAFS];
} edict_leaf_bucket_t;
static edict_leaf_bucket_t *edict_leaf_buckets;
static edict_leaf_bucket_t **edict_leaf_bucket_tail = &edict_leaf_buckets;
static edict_leaf_t *free_edict_leaf_list;
static edict_leaf_t *
alloc_edict_leaf (void)
{
edict_leaf_bucket_t *bucket;
edict_leaf_t *el;
int i;
edict_leaf_t *edict_leaf;
if (!free_edict_leaf_list) {
free_edict_leaf_list = malloc (EDICT_LEAFS * sizeof (edict_leaf_t));
for (i = 0; i < EDICT_LEAFS - 1; i++)
free_edict_leaf_list[i].next = &free_edict_leaf_list[i + 1];
free_edict_leaf_list[i].next = 0;
if ((el = free_edict_leaf_list)) {
free_edict_leaf_list = el->next;
el->next = 0;
return el;
}
edict_leaf = free_edict_leaf_list;
free_edict_leaf_list = free_edict_leaf_list->next;
edict_leaf->next = 0;
return edict_leaf;
bucket = malloc (sizeof (edict_leaf_bucket_t));
bucket->next = 0;
*edict_leaf_bucket_tail = bucket;
edict_leaf_bucket_tail = &bucket->next;
for (el = bucket->edict_leafs, i = 0; i < EDICT_LEAFS - 1; i++, el++)
el->next = el + 1;
el->next = 0;
free_edict_leaf_list = bucket->edict_leafs;
return alloc_edict_leaf ();
}
static void
@ -83,6 +98,23 @@ free_edict_leafs (edict_leaf_t **edict_leafs)
*edict_leafs = 0;
}
void
SV_FreeAllEdictLeafs (void)
{
edict_leaf_bucket_t *bucket;
edict_leaf_t *el;
int i;
for (bucket = edict_leaf_buckets; bucket; bucket = bucket->next) {
for (el = bucket->edict_leafs, i = 0; i < EDICT_LEAFS - 1; i++, el++)
el->next = el + 1;
el->next = bucket->next ? bucket->next->edict_leafs : 0;
}
free_edict_leaf_list = 0;
if (edict_leaf_buckets)
free_edict_leaf_list = edict_leaf_buckets->edict_leafs;
}
/*
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't

View file

@ -350,6 +350,7 @@ SV_SpawnServer (const char *server)
// load progs to get entity field count which determines how big each
// edict is
SV_LoadProgs ();
SV_FreeAllEdictLeafs ();
SV_SetupUserCommands ();
Info_SetValueForStarKey (svs.info, "*progs", va ("%i", sv_pr_state.crc),
!sv_highchars->int_val);

View file

@ -51,24 +51,39 @@ static __attribute__ ((used)) const char rcsid[] =
#include "world.h"
#define EDICT_LEAFS 32
typedef struct edict_leaf_bucket_s {
struct edict_leaf_bucket_s *next;
edict_leaf_t edict_leafs[EDICT_LEAFS];
} edict_leaf_bucket_t;
static edict_leaf_bucket_t *edict_leaf_buckets;
static edict_leaf_bucket_t **edict_leaf_bucket_tail = &edict_leaf_buckets;
static edict_leaf_t *free_edict_leaf_list;
static edict_leaf_t *
alloc_edict_leaf (void)
{
edict_leaf_bucket_t *bucket;
edict_leaf_t *el;
int i;
edict_leaf_t *edict_leaf;
if (!free_edict_leaf_list) {
free_edict_leaf_list = malloc (EDICT_LEAFS * sizeof (edict_leaf_t));
for (i = 0; i < EDICT_LEAFS - 1; i++)
free_edict_leaf_list[i].next = &free_edict_leaf_list[i + 1];
free_edict_leaf_list[i].next = 0;
if ((el = free_edict_leaf_list)) {
free_edict_leaf_list = el->next;
el->next = 0;
return el;
}
edict_leaf = free_edict_leaf_list;
free_edict_leaf_list = free_edict_leaf_list->next;
edict_leaf->next = 0;
return edict_leaf;
bucket = malloc (sizeof (edict_leaf_bucket_t));
bucket->next = 0;
*edict_leaf_bucket_tail = bucket;
edict_leaf_bucket_tail = &bucket->next;
for (el = bucket->edict_leafs, i = 0; i < EDICT_LEAFS - 1; i++, el++)
el->next = el + 1;
el->next = 0;
free_edict_leaf_list = bucket->edict_leafs;
return alloc_edict_leaf ();
}
static void
@ -83,6 +98,23 @@ free_edict_leafs (edict_leaf_t **edict_leafs)
*edict_leafs = 0;
}
void
SV_FreeAllEdictLeafs (void)
{
edict_leaf_bucket_t *bucket;
edict_leaf_t *el;
int i;
for (bucket = edict_leaf_buckets; bucket; bucket = bucket->next) {
for (el = bucket->edict_leafs, i = 0; i < EDICT_LEAFS - 1; i++, el++)
el->next = el + 1;
el->next = bucket->next ? bucket->next->edict_leafs : 0;
}
free_edict_leaf_list = 0;
if (edict_leaf_buckets)
free_edict_leaf_list = edict_leaf_buckets->edict_leafs;
}
/*
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't