diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index a5adb615..62c5dd70 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -519,7 +519,7 @@ void CL_ParsePacketEntities (qboolean delta) if (newindex >= newp->max_entities) { newp->max_entities = newindex+1; - newp->entities = BZ_Realloc(newp->entities, sizeof(entity_state_t)*newp->max_entities); + newp->entities = BZ_Realloc(newp->entities, sizeof(entity_state_t)*newp->max_entities); } if (oldindex >= oldp->max_entities) Host_EndGame("Old packet entity too big\n"); @@ -1425,8 +1425,10 @@ void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t * if (snew->number >= cl.maxlerpents) { - cl.maxlerpents = snew->number+16; - cl.lerpents = BZ_Realloc(cl.lerpents, cl.maxlerpents*sizeof(lerpents_t)); + int newmaxle = snew->number+16; + cl.lerpents = BZ_Realloc(cl.lerpents, newmaxle*sizeof(lerpents_t)); + memset(cl.lerpents + cl.maxlerpents, 0, sizeof(lerpents_t)*(newmaxle - cl.maxlerpents)); + cl.maxlerpents = newmaxle; } le = &cl.lerpents[snew->number]; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 533183d5..93aebadc 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -3664,6 +3664,8 @@ void Host_Shutdown(void) Cvar_Shutdown(); Validation_FlushFileList(); + + Memory_DeInit(); } #ifdef CLIENTONLY diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index e8b9f75a..8cdfa1d8 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2567,7 +2567,7 @@ qboolean CL_CheckBaselines (int size) if (size < cl_baselines_count) return true; - cl_baselines = BZ_Realloc(cl_baselines, sizeof(*cl_baselines)*size); + cl_baselines = BZ_Realloc(cl_baselines, sizeof(*cl_baselines)*size); for (i = cl_baselines_count; i < size; i++) { memcpy(cl_baselines + i, &nullentitystate, sizeof(*cl_baselines)); diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index c5ef19d8..e7ba68d7 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -117,6 +117,7 @@ int VARGS Plug_Draw_LoadImage(void *offset, unsigned int mask, const int *arg) { pluginimagearraylen++; pluginimagearray = BZ_Realloc(pluginimagearray, pluginimagearraylen*sizeof(pluginimagearray_t)); + pluginimagearray[i].pic = NULL; } if (pluginimagearray[i].pic) diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 4c2bdf61..a5d40483 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -212,7 +212,7 @@ int Script_LoadFile(char *filename) if (i == maxscripts) { maxscripts++; - scripts = BZ_Realloc(scripts, sizeof(script_t)*maxscripts); + scripts = BZ_Realloc(scripts, sizeof(script_t)*maxscripts); } sc = scripts+i; diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 830c5a1f..c560b19d 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -3859,6 +3859,18 @@ qboolean CSQC_CenterPrint(char *cmd) //this protocol allows up to 32767 edicts. #ifdef PEXT_CSQC +void CSQC_EntityCheck(int entnum) +{ + int newmax; + + if (entnum >= maxcsqcentities) + { + newmax = entnum+64; + csqcent = BZ_Realloc(csqcent, sizeof(*csqcent)*newmax); + memset(csqcent + maxcsqcentities, 0, newmax - maxcsqcentities); + maxcsqcentities = newmax; + } +} int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation) { @@ -3868,11 +3880,7 @@ int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float if (!csqcprogs || !csqcg.serversound) return false; - if (entnum >= maxcsqcentities) - { - maxcsqcentities = entnum+64; - csqcent = BZ_Realloc(csqcent, sizeof(*csqcent)*maxcsqcentities); - } + CSQC_EntityCheck(entnum); ent = csqcent[entnum]; if (!ent) return false; @@ -3926,11 +3934,8 @@ void CSQC_ParseEntities(void) if (!entnum) Host_EndGame("CSQC cannot remove world!\n"); - if (entnum >= maxcsqcentities) - { - maxcsqcentities = entnum+64; - csqcent = BZ_Realloc(csqcent, sizeof(*csqcent)*maxcsqcentities); - } + CSQC_EntityCheck(entnum); + if (cl_csqcdebug.value) Con_Printf("Remove %i\n", entnum); @@ -3946,11 +3951,7 @@ void CSQC_ParseEntities(void) } else { - if (entnum >= maxcsqcentities) - { - maxcsqcentities = entnum+64; - csqcent = BZ_Realloc(csqcent, sizeof(*csqcent)*maxcsqcentities); - } + CSQC_EntityCheck(entnum); if (cl.csqcdebug) { diff --git a/engine/client/r_part.c b/engine/client/r_part.c index ea8f139a..5ed5d78a 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -209,7 +209,6 @@ static part_type_t *P_GetParticleType(char *name) ptype->cliptype = -1; ptype->emit = -1; - if (oldlist) { part_run_list=NULL; @@ -219,13 +218,10 @@ static part_type_t *P_GetParticleType(char *name) part_type[i].nexttorun = (part_type_t*)((char*)part_type[i].nexttorun - (char*)oldlist + (char*)part_type); } -/* - Due to BZ_Realloc we can assume all of this anyway ptype->loaded = 0; ptype->ramp = NULL; ptype->particles = NULL; ptype->beams = NULL; -*/ return ptype; } diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 704e5d02..f8f2b4f9 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -620,12 +620,6 @@ void Sys_Quit (void) CloseHandle (qwclsemaphore); #endif -/* Yeah, right, just wishful thinking. -#ifdef _DEBUG - if (Z_Allocated()) - MessageBox(0, "Some memory was left allocated", "Mem was left", 0); -#endif -*/ SetHookState(false); diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 21839122..cf9c919c 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -179,8 +179,10 @@ void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags) if (newnum >= numplugbuiltins) { - numplugbuiltins = newnum+128; - plugbuiltins = BZ_Realloc(plugbuiltins, sizeof(Plug_Plugins_t)*numplugbuiltins); + int newbuiltins = newnum+128; + plugbuiltins = BZ_Realloc(plugbuiltins, sizeof(Plug_Plugins_t)*newbuiltins); + memset(plugbuiltins + numplugbuiltins, 0, sizeof(Plug_Plugins_t)*(newbuiltins - numplugbuiltins)); + numplugbuiltins = newbuiltins; } //got an empty number. diff --git a/engine/common/zone.c b/engine/common/zone.c index 07cc6e9c..a16f965e 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -64,10 +64,254 @@ void Cache_FreeHigh (int new_high_hunk); qbyte sentinalkey; #endif +#define TAGLESS 1 + +typedef struct memheader_s { + int size; + int tag; +} memheader_t; + +typedef struct zone_s { + struct zone_s *next; + struct zone_s *pvdn; // down if first, previous if not + memheader_t mh; +} zone_t; +zone_t *zone_head; +#ifdef MULTITHREAD +void *zonelock; +#endif + +void *VARGS Z_TagMalloc(int size, int tag) +{ + zone_t *zone; + + zone = (zone_t *)malloc(size + sizeof(zone_t)); + if (!zone) + Sys_Error("Z_Malloc: Failed on allocation of %i bytes", size); + Q_memset(zone, 0, size + sizeof(zone_t)); + zone->mh.tag = tag; + zone->mh.size = size; + +#ifdef MULTITHREAD + if (zonelock) + Sys_LockMutex(zonelock); +#endif + if (zone_head == NULL) + zone_head = zone; + else if (zone_head->mh.tag == tag) + { + zone->next = zone_head->next; + zone_head->next = zone; + } + else + { + zone_t *s = zone_head->pvdn; + + while (s && s->mh.tag != tag) + s = s->pvdn; + + if (s) + { // tag match + zone->next = s->next; + s->next = zone; + } + else + { + zone->pvdn = zone_head; + zone_head = zone; + } + } +#ifdef MULTITHREAD + if (zonelock) + Sys_UnlockMutex(zonelock); +#endif + + return (void *)(zone + 1); +} + +void *ZF_Malloc(int size) +{ + return calloc(size, 1); +} + +void *Z_Malloc(int size) +{ + void *mem = ZF_Malloc(size); + if (!mem) + Sys_Error("Z_Malloc: Failed on allocation of %i bytes", size); + + return mem; +} + +void VARGS Z_TagFree(void *mem) +{ + zone_t *zone = ((zone_t *)mem) - 1; + +#ifdef MULTITHREAD + if (zonelock) + Sys_LockMutex(zonelock); +#endif + if (zone->next) + zone->next->pvdn = zone->pvdn; + if (zone->pvdn && zone->pvdn->mh.tag == zone->mh.tag) + zone->pvdn->next = zone->next; + else + { // zone is first entry in a tag list + zone_t *s = zone_head; + + if (zone != s) + { // traverse and update down list + while (s->pvdn != zone) + s = s->next; + + s->pvdn = zone->pvdn; + } + } + + if (zone == zone_head) + { // freeing head node so update head pointer + if (zone->next) // move to next, pvdn should be maintained properly + zone_head = zone->next; + else // no more entries with this tag so move head down + zone_head = zone->pvdn; + } +#ifdef MULTITHREAD + if (zonelock) + Sys_UnlockMutex(zonelock); +#endif + + free(zone); +} + +void VARGS Z_Free(void *mem) +{ + free(mem); +} + +void VARGS Z_FreeTags(int tag) +{ + zone_t *taglist; + zone_t *t; + +#ifdef MULTITHREAD + if (zonelock) + Sys_LockMutex(zonelock); +#endif + if (zone_head) + { + if (zone_head->mh.tag == tag) + { // just pull off the head + taglist = zone_head; + zone_head = zone_head->pvdn; + } + else + { // search for tag list and isolate it + zone_t *z; + z = zone_head; + while (z->next != NULL && z->next->mh.tag != tag) + z = z->next; + + if (z->next == NULL) + taglist = NULL; + else + { + taglist = z->next; + z->next = z->next->next; + } + } + } + else + taglist = NULL; +#ifdef MULTITHREAD + if (zonelock) + Sys_UnlockMutex(zonelock); +#endif + + // actually free list + while (taglist != NULL) + { + t = taglist->next; + free(taglist); + taglist = t; + } +} + +/* +void *Z_Realloc(void *data, int newsize) +{ + memheader_t *memref; + + if (!data) + return Z_Malloc(newsize); + + memref = ((memheader_t *)data) - 1; + + if (memref[0].tag != TAGLESS) + { // allocate a new block and copy since we need to maintain the lists + zone_t *zone = ((zone_t *)data) - 1; + int size = zone->mh.size; + if (size != newsize) + { + void *newdata = Z_Malloc(newsize); + + if (size > newsize) + size = newsize; + memcpy(newdata, data, size); + + Z_Free(data); + data = newdata; + } + } + else + { + int oldsize = memref[0].size; + memref = realloc(memref, newsize + sizeof(memheader_t)); + memref->size = newsize; + if (newsize > oldsize) + memset((qbyte *)memref + sizeof(memheader_t) + oldsize, 0, newsize - oldsize); + data = ((memheader_t *)memref) + 1; + } + + return data; +} +*/ + +void *BZF_Malloc(int size) //BZ_Malloc but allowed to fail - like straight malloc. +{ + return calloc(size, 1); // TODO: this should be malloc but some code still assumes this is an alias to Z_Malloc +} + +void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensative data structures. +{ + void *mem = BZF_Malloc(size); + if (!mem) + Sys_Error("BZ_Malloc: Failed on allocation of %i bytes", size); + + return mem; +} + +void *BZF_Realloc(void *data, int newsize) +{ + return realloc(data, newsize); +} + +void *BZ_Realloc(void *data, int newsize) +{ + void *mem = BZF_Realloc(data, newsize); + + if (!mem) + Sys_Error("BZ_Realloc: Failed on reallocation of %i bytes", newsize); + + return mem; +} + +void BZ_Free(void *data) +{ + free(data); +} - -#ifdef NOZONE //zone memory is for small dynamic things. +#if 0 //NOZONE //zone memory is for small dynamic things. /* void *Z_TagMalloc(int size, int tag) { @@ -139,24 +383,6 @@ void Z_CheckSentinals(void) } }*/ -int Z_Allocated(void) -{ - zone_t *zone; - int used = 0; - for(zone = zone_head; zone; zone=zone->next) - { - used += zone->size; - } - - return used; -} - -int Z_MemSize(void *c) -{ - zone_t *nz; - nz = ((zone_t *)((char*)c-ZONEDEBUG))-1; - return nz->size; -} void VARGS Z_Free (void *c) { @@ -553,7 +779,7 @@ void Zone_Print_f(void) Con_Printf(CON_NOTICE "Overhead %i bytes\n", overhead); } -#else +#elif 0//#else @@ -806,29 +1032,6 @@ void Z_Print (memzone_t *zone) } -/* -======================== -Z_CheckHeap -======================== -*/ -void Z_CheckHeap (void) -{ - memblock_t *block; - - for (block = mainzone->blocklist.next ; ; block = block->next) - { - if (block->next == &mainzone->blocklist) - break; // all blocks have been hit - if ( (qbyte *)block + block->size != (qbyte *)block->next) - Sys_Error ("Z_CheckHeap: block size does not touch the next block\n"); - if ( block->next->prev != block) - Sys_Error ("Z_CheckHeap: next block doesn't have proper back link\n"); - if (!block->tag && !block->next->tag) - Sys_Error ("Z_CheckHeap: two consecutive free blocks\n"); - } -} - - @@ -1456,7 +1659,6 @@ void Cache_Report (void) void Hunk_Print_f (void) { cache_system_t *cs; - zone_t *zone; int zoneblocks; int cacheused; int zoneused; @@ -1469,19 +1671,27 @@ void Hunk_Print_f (void) { cacheused += cs->size; } - for(zone = zone_head; zone; zone=zone->next) - { - zoneused += zone->size + sizeof(zone_t); - zoneblocks++; - } Con_Printf("Cache: %iKB\n", cacheused/1024); - Con_Printf("Zone: %i containing %iKB\n", zoneblocks, zoneused/1024); +#if 0 + { + zone_t *zone; + + for(zone = zone_head; zone; zone=zone->next) + { + zoneused += zone->size + sizeof(zone_t); + zoneblocks++; + } + Con_Printf("Zone: %i containing %iKB\n", zoneblocks, zoneused/1024); + } +#endif } void Cache_Init(void) { Cmd_AddCommand ("flush", Cache_Flush); Cmd_AddCommand ("hunkprint", Hunk_Print_f); +#if 0 Cmd_AddCommand ("zoneprint", Zone_Print_f); +#endif #ifdef NAMEDMALLOCS Cmd_AddCommand ("zonegroups", Zone_Groups_f); #endif @@ -1938,7 +2148,7 @@ Memory_Init */ void Memory_Init (void *buf, int size) { -#ifndef NOZONE +#if 0 //ndef NOZONE int p; int zonesize = DYNAMIC_SIZE; #endif @@ -1955,7 +2165,12 @@ void Memory_Init (void *buf, int size) Cache_Init (); -#ifndef NOZONE +#ifdef MULTITHREAD + if (!zonelock) + zonelock = Sys_CreateMutex(); // this can fail! +#endif + +#if 0 //ndef NOZONE p = COM_CheckParm ("-zone"); if (p) { @@ -1969,3 +2184,13 @@ void Memory_Init (void *buf, int size) #endif } +void Memory_DeInit(void) +{ +#ifdef MULTITHREAD + if (zonelock) + { + Sys_DestroyMutex(zonelock); + zonelock = NULL; + } +#endif +} \ No newline at end of file diff --git a/engine/common/zone.h b/engine/common/zone.h index 1d815e6d..7887ae20 100644 --- a/engine/common/zone.h +++ b/engine/common/zone.h @@ -84,31 +84,23 @@ Zone block */ void Memory_Init (void *buf, int size); +void Memory_DeInit(void); void VARGS Z_Free (void *ptr); -int Z_MemSize(void *c); -void *Z_Malloc (int size); // returns 0 filled memory -void *Z_MallocNamed (int size, char *, int); // returns 0 filled memory +void *Z_Malloc (int size); // returns 0 filled memory +void *ZF_Malloc (int size); // allowed to fail //#define Z_Malloc(x) Z_MallocNamed2(x, __FILE__, __LINE__ ) void *VARGS Z_TagMalloc (int size, int tag); +void VARGS Z_TagFree(void *ptr); void VARGS Z_FreeTags(int tag); - -void Z_DumpHeap (void); -void Z_CheckHeap (void); -int Z_FreeMemory (void); - -int Z_Allocated(void); - -#ifdef _DEBUG -#define NAMEDMALLOCS -#endif +//void *Z_Realloc (void *ptr, int size); //Big Zone: allowed to fail, doesn't clear. The expectation is a large file, rather than sensative data structures. //(this is a nicer name for malloc) void *BZ_Malloc(int size); void *BZF_Malloc(int size); void *BZ_Realloc(void *ptr, int size); -void *BZ_NamedRealloc(void *ptr, int size, char *, int); +void *BZF_Realloc(void *data, int newsize); void BZ_Free(void *ptr); #ifdef NAMEDMALLOCS diff --git a/engine/d3d/d3d_rsurf.c b/engine/d3d/d3d_rsurf.c index dd9cd79e..e0868981 100644 --- a/engine/d3d/d3d_rsurf.c +++ b/engine/d3d/d3d_rsurf.c @@ -989,17 +989,22 @@ int D3DFillBlock (int texnum, int w, int h, int x, int y) while (texnum >= numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = 0; + lightmap[numlightmaps+1] = 0; + lightmap[numlightmaps+2] = 0; + lightmap[numlightmaps+3] = 0; + lightmap_d3dtextures = BZ_Realloc(lightmap_d3dtextures, sizeof(*lightmap_d3dtextures)*(numlightmaps+4)); -// lightmap_textures[numlightmaps+0] = texture_extension_number++; -// lightmap_textures[numlightmaps+1] = texture_extension_number++; -// lightmap_textures[numlightmaps+2] = texture_extension_number++; -// lightmap_textures[numlightmaps+3] = texture_extension_number++; + lightmap_d3dtextures[numlightmaps+0] = 0; + lightmap_d3dtextures[numlightmaps+1] = 0; + lightmap_d3dtextures[numlightmaps+2] = 0; + lightmap_d3dtextures[numlightmaps+3] = 0; deluxmap_d3dtextures = BZ_Realloc(deluxmap_d3dtextures, sizeof(*deluxmap_d3dtextures)*(numlightmaps+4)); -// deluxmap_textures[numlightmaps+0] = texture_extension_number++; -// deluxmap_textures[numlightmaps+1] = texture_extension_number++; -// deluxmap_textures[numlightmaps+2] = texture_extension_number++; -// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + deluxmap_d3dtextures[numlightmaps+0] = 0; + deluxmap_d3dtextures[numlightmaps+1] = 0; + deluxmap_d3dtextures[numlightmaps+2] = 0; + deluxmap_d3dtextures[numlightmaps+3] = 0; numlightmaps+=4; } for (i = texnum; i >= 0; i--) @@ -1035,17 +1040,22 @@ int D3D7_AllocBlock (int w, int h, int *x, int *y) if (texnum == numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = 0; + lightmap[numlightmaps+1] = 0; + lightmap[numlightmaps+2] = 0; + lightmap[numlightmaps+3] = 0; + lightmap_d3dtextures = BZ_Realloc(lightmap_d3dtextures, sizeof(*lightmap_d3dtextures)*(numlightmaps+4)); -// lightmap_textures[numlightmaps+0] = texture_extension_number++; -// lightmap_textures[numlightmaps+1] = texture_extension_number++; -// lightmap_textures[numlightmaps+2] = texture_extension_number++; -// lightmap_textures[numlightmaps+3] = texture_extension_number++; + lightmap_d3dtextures[numlightmaps+0] = 0; + lightmap_d3dtextures[numlightmaps+1] = 0; + lightmap_d3dtextures[numlightmaps+2] = 0; + lightmap_d3dtextures[numlightmaps+3] = 0; deluxmap_d3dtextures = BZ_Realloc(deluxmap_d3dtextures, sizeof(*deluxmap_d3dtextures)*(numlightmaps+4)); -// deluxmap_textures[numlightmaps+0] = texture_extension_number++; -// deluxmap_textures[numlightmaps+1] = texture_extension_number++; -// deluxmap_textures[numlightmaps+2] = texture_extension_number++; -// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + deluxmap_d3dtextures[numlightmaps+0] = 0; + deluxmap_d3dtextures[numlightmaps+1] = 0; + deluxmap_d3dtextures[numlightmaps+2] = 0; + deluxmap_d3dtextures[numlightmaps+3] = 0; numlightmaps+=4; } if (!lightmap[texnum]) diff --git a/engine/d3d9/d3d9_rsurf.c b/engine/d3d9/d3d9_rsurf.c index 4076527c..971f9bbd 100644 --- a/engine/d3d9/d3d9_rsurf.c +++ b/engine/d3d9/d3d9_rsurf.c @@ -990,17 +990,22 @@ int D3D9_FillBlock (int texnum, int w, int h, int x, int y) while (texnum >= numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = 0; + lightmap[numlightmaps+1] = 0; + lightmap[numlightmaps+2] = 0; + lightmap[numlightmaps+3] = 0; + lightmap_d3d9textures = BZ_Realloc(lightmap_d3d9textures, sizeof(*lightmap_d3d9textures)*(numlightmaps+4)); -// lightmap_textures[numlightmaps+0] = texture_extension_number++; -// lightmap_textures[numlightmaps+1] = texture_extension_number++; -// lightmap_textures[numlightmaps+2] = texture_extension_number++; -// lightmap_textures[numlightmaps+3] = texture_extension_number++; + lightmap_d3d9textures[numlightmaps+0] = 0; + lightmap_d3d9textures[numlightmaps+1] = 0; + lightmap_d3d9textures[numlightmaps+2] = 0; + lightmap_d3d9textures[numlightmaps+3] = 0; deluxmap_d3d9textures = BZ_Realloc(deluxmap_d3d9textures, sizeof(*deluxmap_d3d9textures)*(numlightmaps+4)); -// deluxmap_textures[numlightmaps+0] = texture_extension_number++; -// deluxmap_textures[numlightmaps+1] = texture_extension_number++; -// deluxmap_textures[numlightmaps+2] = texture_extension_number++; -// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + deluxmap_d3d9textures[numlightmaps+0] = 0; + deluxmap_d3d9textures[numlightmaps+1] = 0; + deluxmap_d3d9textures[numlightmaps+2] = 0; + deluxmap_d3d9textures[numlightmaps+3] = 0; numlightmaps+=4; } for (i = texnum; i >= 0; i--) @@ -1036,17 +1041,22 @@ int D3D9_AllocBlock (int w, int h, int *x, int *y) if (texnum == numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = 0; + lightmap[numlightmaps+1] = 0; + lightmap[numlightmaps+2] = 0; + lightmap[numlightmaps+3] = 0; + lightmap_d3d9textures = BZ_Realloc(lightmap_d3d9textures, sizeof(*lightmap_d3d9textures)*(numlightmaps+4)); -// lightmap_textures[numlightmaps+0] = texture_extension_number++; -// lightmap_textures[numlightmaps+1] = texture_extension_number++; -// lightmap_textures[numlightmaps+2] = texture_extension_number++; -// lightmap_textures[numlightmaps+3] = texture_extension_number++; + lightmap_d3d9textures[numlightmaps+0] = 0; + lightmap_d3d9textures[numlightmaps+1] = 0; + lightmap_d3d9textures[numlightmaps+2] = 0; + lightmap_d3d9textures[numlightmaps+3] = 0; deluxmap_d3d9textures = BZ_Realloc(deluxmap_d3d9textures, sizeof(*deluxmap_d3d9textures)*(numlightmaps+4)); -// deluxmap_textures[numlightmaps+0] = texture_extension_number++; -// deluxmap_textures[numlightmaps+1] = texture_extension_number++; -// deluxmap_textures[numlightmaps+2] = texture_extension_number++; -// deluxmap_textures[numlightmaps+3] = texture_extension_number++; + deluxmap_d3d9textures[numlightmaps+0] = 0; + deluxmap_d3d9textures[numlightmaps+1] = 0; + deluxmap_d3d9textures[numlightmaps+2] = 0; + deluxmap_d3d9textures[numlightmaps+3] = 0; numlightmaps+=4; } if (!lightmap[texnum]) diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 21ab3090..1e758697 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -5217,7 +5217,7 @@ void APIENTRY SH_End (void) if (sh_maxindicies != i) { sh_maxindicies = i; - sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies)); + sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies)); } //add the extra triangles for (i = 0; i < sh_vertnum; i+=4) diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 41ec6474..b9386625 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -3164,7 +3164,12 @@ int GLAllocBlock (int w, int h, int *x, int *y) { if (texnum == numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { - lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = NULL; + lightmap[numlightmaps+1] = NULL; + lightmap[numlightmaps+2] = NULL; + lightmap[numlightmaps+3] = NULL; + lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4)); lightmap_textures[numlightmaps+0] = texture_extension_number++; lightmap_textures[numlightmaps+1] = texture_extension_number++; @@ -3226,14 +3231,19 @@ int GLFillBlock (int texnum, int w, int h, int x, int y) int i, l; while (texnum >= numlightmaps) //allocate 4 more lightmap slots. not much memory usage, but we don't want any caps here. { - lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); - lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4)); + lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(numlightmaps+4)); + lightmap[numlightmaps+0] = NULL; + lightmap[numlightmaps+1] = NULL; + lightmap[numlightmaps+2] = NULL; + lightmap[numlightmaps+3] = NULL; + + lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4)); lightmap_textures[numlightmaps+0] = texture_extension_number++; lightmap_textures[numlightmaps+1] = texture_extension_number++; lightmap_textures[numlightmaps+2] = texture_extension_number++; lightmap_textures[numlightmaps+3] = texture_extension_number++; - deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4)); + deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4)); deluxmap_textures[numlightmaps+0] = texture_extension_number++; deluxmap_textures[numlightmaps+1] = texture_extension_number++; deluxmap_textures[numlightmaps+2] = texture_extension_number++; diff --git a/engine/http/iwebiface.c b/engine/http/iwebiface.c index 820f9a8b..ac452218 100644 --- a/engine/http/iwebiface.c +++ b/engine/http/iwebiface.c @@ -409,22 +409,14 @@ void IWebShutdown(void) //replacement for Z_Malloc. It simply allocates up to a reserve ammount. void *IWebMalloc(int size) { - char *mem = Z_TagMalloc(size+32768, 15); - if (!mem) - return NULL; //bother - - Z_Free(mem); - return Z_Malloc(size); //allocate the real ammount + void *mem = BZF_Malloc(size); + memset(mem, 0, size); + return mem; } void *IWebRealloc(void *old, int size) { - char *mem = Z_TagMalloc(size+32768, 15); - if (!mem) //make sure there will be padding left - return NULL; //bother - - Z_Free(mem); - return BZ_Realloc(old, size); + return BZF_Realloc(old, size); } #endif diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 6faa169d..3ec8f2c5 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -5477,7 +5477,7 @@ void PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) return; } ((int *)s)[0] = 0xabcd1234; - Z_Free(s); + Z_TagFree(s); } void PF_strlen(progfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -6348,7 +6348,7 @@ typedef struct sqlserver_s { void *thread; // worker thread for server MYSQL *mysql; // mysql server - qboolean active; // set to false to kill thread + volatile qboolean active; // set to false to kill thread void *requestlock; // mutex for queue read/write void *resultlock; // mutex for queue read/write int querynum; // next reference number for queries @@ -6377,14 +6377,12 @@ queryresult_t *SQL_PullResult(sqlserver_t *server) queryresult_t *qres; Sys_LockMutex(server->resultlock); qres = server->results; - if (!qres) + if (qres) { - Sys_UnlockMutex(server->resultlock); - return NULL; + server->results = qres->next; + if (!server->results) + server->resultslast = NULL; } - server->results = qres->next; - if (!server->results) - server->resultslast = NULL; Sys_UnlockMutex(server->resultlock); return qres; @@ -6406,14 +6404,12 @@ queryrequest_t *SQL_PullRequest(sqlserver_t *server) queryrequest_t *qreq; Sys_LockMutex(server->requestlock); qreq = server->requests; - if (!qreq) + if (qreq) { - Sys_UnlockMutex(server->requestlock); - return NULL; + server->requests = qreq->next; + if (!server->requests) + server->requestslast = NULL; } - server->requests = qreq->next; - if (!server->requests) - server->requestslast = NULL; Sys_UnlockMutex(server->requestlock); return qreq; @@ -6427,8 +6423,9 @@ int sql_serverworker(void *sref) sqlserver_t *server = (sqlserver_t *)sref; char *error = NULL; my_bool reconnect = 1; + int tinit; - if (mysql_thread_init()) + if (tinit = mysql_thread_init()) error = "MYSQL thread init failed"; else if (!(server->mysql = mysql_init(NULL))) error = "MYSQL init failed"; @@ -6483,36 +6480,49 @@ int sql_serverworker(void *sref) if (qerror) qesize = Q_strlen(qerror); - qres = (queryresult_t *)Z_Malloc(sizeof(queryresult_t) + qesize); - if (qerror) - Q_strncpy(qres->error, qerror, qesize); - qres->result = mysqlres; - qres->rows = rows; - qres->columns = columns; - qres->request = qreq; - qres->eof = true; // store result has no more rows to read afterwards - qreq->next = NULL; + qres = (queryresult_t *)ZF_Malloc(sizeof(queryresult_t) + qesize); + if (qres) + { + if (qerror) + Q_strncpy(qres->error, qerror, qesize); + qres->result = mysqlres; + qres->rows = rows; + qres->columns = columns; + qres->request = qreq; + qres->eof = true; // store result has no more rows to read afterwards + qreq->next = NULL; - SQL_PushResult(server, qres); + SQL_PushResult(server, qres); + } + else // we're screwed here so bomb out + { + server->active = false; + error = "MALLOC ERROR! Unable to allocate query result!"; + break; + } } } + if (server->mysql) + mysql_close(server->mysql); + // if we have a server error we still need to put it on the queue if (error) { int esize = Q_strlen(error); queryresult_t *qres = (queryresult_t *)Z_Malloc(sizeof(queryresult_t) + esize); + if (qres) + { // hopefully the mysql_close gained us some memory otherwise we're pretty screwed + qres->rows = qres->columns = -1; + Q_strncpy(qres->error, error, esize); - qres->rows = qres->columns = -1; - Q_strncpy(qres->error, error, esize); - - SQL_PushResult(server, qres); + SQL_PushResult(server, qres); + } } - mysql_close(server->mysql); - - mysql_thread_end(); + if (!tinit) + mysql_thread_end(); return 0; } @@ -6553,8 +6563,28 @@ void PF_sqlconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) server->requestlock = Sys_CreateMutex(); server->resultlock = Sys_CreateMutex(); - server->thread = Sys_CreateThread(sql_serverworker, (void *)server, 1024); + if (!server->requestlock || !server->resultlock) + { + if (server->requestlock) + Sys_DestroyMutex(server->requestlock); + if (server->resultlock) + Sys_DestroyMutex(server->resultlock); + Z_Free(server); + sqlservercount--; + G_FLOAT(OFS_RETURN) = -1; + return; + } + server->thread = Sys_CreateThread(sql_serverworker, (void *)server, 1024); + + if (!server->thread) + { + Z_Free(server); + sqlservercount--; + G_FLOAT(OFS_RETURN) = -1; + return; + } + G_FLOAT(OFS_RETURN) = serverref; } @@ -6576,10 +6606,10 @@ void PF_sqlopenquery (progfuncs_t *prinst, struct globalvars_s *pr_globals) int callfunc = G_INT(OFS_PARM1); char *querystr = PF_VarString(prinst, 2, pr_globals); int qsize = Q_strlen(querystr); - queryrequest_t *qreq = (queryrequest_t *)Z_Malloc(sizeof(queryrequest_t) + qsize); + queryrequest_t *qreq = (queryrequest_t *)ZF_Malloc(sizeof(queryrequest_t) + qsize); int querynum; - if (serverref < 0 || serverref >= sqlservercount || sqlservers[serverref]->active == false) + if (!qreq || serverref < 0 || serverref >= sqlservercount || sqlservers[serverref]->active == false) { G_FLOAT(OFS_RETURN) = -1; return; diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 5a1948b4..c26c9287 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -240,6 +240,8 @@ void SV_Shutdown (void) #ifdef IWEB_H__ IWebShutdown(); #endif + + Memory_DeInit(); } /* diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index abc7c0e8..c1ff3078 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -675,7 +675,7 @@ qboolean SVQ2_InitGameProgs(void) import.WriteAngle = PFQ2_WriteAngle; import.TagMalloc = Z_TagMalloc; - import.TagFree = Z_Free; + import.TagFree = Z_TagFree; import.FreeTags = Z_FreeTags; import.cvar = Q2Cvar_Get; diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 7556f6cc..43fc71e9 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -1653,13 +1653,19 @@ int BL_AvailableMemory(void) } void *BL_Malloc(int size) { + int *mem; botlibmemoryavailable-=size; - return Z_TagMalloc(size, Z_TAG_BOTLIB); + + mem = (int *)Z_TagMalloc(size+sizeof(int), Z_TAG_BOTLIB); + mem[0] = size; + + return (void *)(mem + 1); } void BL_Free(void *mem) { - botlibmemoryavailable+=Z_MemSize(mem); - Z_Free(mem); + int *memref = ((int *)mem) - 1; + botlibmemoryavailable+=memref[0]; + Z_Free(memref); } void *BL_HunkMalloc(int size) {