From cdd3bad8132190dc036cf43c826e76cfb4f54cf5 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Mon, 21 Oct 2024 09:34:09 -0500 Subject: [PATCH] Add level pool allocator and use it for mobj, precip, thinkers This should substantially reduce the number of malloc/free calls made to create and destroy mobjs, especially during level load and net save/load. memory_resource standard header is not available on the OSX deployment target we are using, so I had to write my own fixed size pool allocator. --- src/core/memory.cpp | 81 +++++++++++++++++++++- src/core/memory.h | 52 ++++++++++++++ src/d_think.h | 12 +++- src/p_ceilng.c | 9 ++- src/p_floor.c | 24 +++++-- src/p_lights.c | 20 ++++-- src/p_local.h | 1 - src/p_mobj.c | 44 ++++-------- src/p_polyobj.c | 36 +++++++--- src/p_saveg.cpp | 162 +++++++++++++++++++++++++++++++++----------- src/p_setup.cpp | 1 - src/p_slopes.c | 13 ++-- src/p_spec.c | 69 ++++++++++++++----- src/p_tick.c | 8 +-- src/z_zone.cpp | 78 ++++++++++++++++++++- src/z_zone.h | 7 ++ 16 files changed, 493 insertions(+), 124 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 73898fd65..6878c4d1a 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -10,11 +10,13 @@ #include "memory.h" -#include -#include +#include +#include "../cxxutil.hpp" #include "../z_zone.h" +using namespace srb2; + namespace { @@ -58,6 +60,81 @@ void LinearMemory::reset() noexcept } // namespace +PoolAllocator::~PoolAllocator() +{ + release(); +} + +constexpr static size_t nearest_multiple(size_t v, size_t divisor) +{ + return (v + (divisor - 1)) & ~(divisor - 1); +} + +PoolAllocator::ChunkFooter* PoolAllocator::allocate_chunk() +{ + uint8_t* chunk = (uint8_t*)Z_Malloc(nearest_multiple(blocks_ * block_size_, alignof(ChunkFooter)) + sizeof(ChunkFooter), tag_, nullptr); + ChunkFooter* footer = (ChunkFooter*)(chunk + (blocks_ * block_size_)); + footer->next = nullptr; + footer->start = (void*)chunk; + for (size_t i = 0; i < blocks_; i++) + { + FreeBlock* cur = (FreeBlock*)(chunk + (i * block_size_)); + FreeBlock* next = (FreeBlock*)(chunk + ((i + 1) * block_size_)); + cur->next = next; + } + ((FreeBlock*)(chunk + ((blocks_ - 1) * block_size_)))->next = nullptr; + return footer; +} + +void* PoolAllocator::allocate() +{ + if (first_chunk_ == nullptr) + { + SRB2_ASSERT(head_ == nullptr); + + // No chunks allocated yet + first_chunk_ = allocate_chunk(); + head_ = (FreeBlock*)first_chunk_->start; + } + + if (head_->next == nullptr) + { + // Current chunk will be full; allocate another at the end of the list + ChunkFooter* last_chunk = first_chunk_; + while (last_chunk->next != nullptr) + { + last_chunk = last_chunk->next; + } + ChunkFooter* new_chunk = allocate_chunk(); + last_chunk->next = new_chunk; + head_->next = (FreeBlock*)new_chunk->start; + } + + FreeBlock* ret = head_; + head_ = head_->next; + return ret; +} + +void PoolAllocator::deallocate(void* p) +{ + FreeBlock* block = reinterpret_cast(p); + block->next = head_; + head_ = block; +} + +void PoolAllocator::release() +{ + ChunkFooter* next = nullptr; + for (ChunkFooter* i = first_chunk_; i != nullptr; i = next) + { + next = i->next; + Z_Free(i->start); + } + + first_chunk_ = nullptr; + head_ = nullptr; +} + static LinearMemory g_frame_memory {4 * 1024 * 1024}; void* Z_Frame_Alloc(size_t size) diff --git a/src/core/memory.h b/src/core/memory.h index 3d75143f2..1f24ab033 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -14,6 +14,58 @@ #include #ifdef __cplusplus + +#include + +namespace srb2 +{ + +/// Pool allocator; manages bulk allocations of same-size block. If the pool is full, +/// allocations will fail by returning nullptr. +class PoolAllocator final +{ + struct FreeBlock + { + FreeBlock* next; + }; + struct ChunkFooter + { + ChunkFooter* next; + void* start; + }; + ChunkFooter* first_chunk_; + FreeBlock* head_; + size_t block_size_; + size_t blocks_; + int32_t tag_; + + ChunkFooter* allocate_chunk(); + +public: + constexpr PoolAllocator(size_t block_size, size_t blocks, int32_t tag) + : first_chunk_(nullptr) + , head_(nullptr) + , block_size_(block_size) + , blocks_(blocks) + , tag_(tag) + {} + PoolAllocator(const PoolAllocator&) = delete; + PoolAllocator(PoolAllocator&&) noexcept = default; + ~PoolAllocator(); + + PoolAllocator& operator=(const PoolAllocator&) = delete; + PoolAllocator& operator=(PoolAllocator&&) noexcept = default; + + void* allocate(); + void deallocate(void* p); + constexpr size_t block_size() const noexcept { return block_size_; }; + + void release(); +}; + +} // namespace srb2 + + extern "C" { #endif // __cpluspplus diff --git a/src/d_think.h b/src/d_think.h index 550ae7a01..1d27cd24d 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -38,6 +38,15 @@ typedef union actionf_p1 acp1; } actionf_t; +typedef enum +{ + /// The allocation is standard e.g. Z_Malloc + TAT_MALLOC, + + /// The allocation is in the pool allocator (e.g. Z_LevelPoolCalloc) + TAT_LEVELPOOL +} thinker_alloc_type_e; + // Historically, "think_t" is yet another function pointer to a routine // to handle an actor. typedef actionf_t think_t; @@ -52,7 +61,8 @@ struct thinker_t // killough 11/98: count of how many other objects reference // this one using pointers. Used for garbage collection. INT32 references; - boolean cachable; + INT32 alloctype; + size_t size; #ifdef PARANOIA INT32 debug_mobjtype; diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 4da793777..5eaea121c 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -12,6 +12,7 @@ /// \file p_ceilng.c /// \brief Ceiling aninmation (lowering, crushing, raising) +#include "d_think.h" #include "doomdef.h" #include "p_local.h" #include "r_fps.h" @@ -273,7 +274,9 @@ static ceiling_t *CreateCeilingThinker(sector_t *sec) return NULL; } - ceiling = Z_Calloc(sizeof (*ceiling), PU_LEVSPEC, NULL); + ceiling = Z_LevelPoolCalloc(sizeof(*ceiling)); + ceiling->thinker.alloctype = TAT_LEVELPOOL; + ceiling->thinker.size = sizeof(*ceiling); P_AddThinker(THINK_MAIN, &ceiling->thinker); sec->ceilingdata = ceiling; @@ -597,7 +600,9 @@ static ceiling_t *CreateCrushThinker(sector_t *sec) return NULL; } - ceiling = Z_Calloc(sizeof (*ceiling), PU_LEVSPEC, NULL); + ceiling = Z_LevelPoolCalloc(sizeof(*ceiling)); + ceiling->thinker.alloctype = TAT_LEVELPOOL; + ceiling->thinker.size = sizeof(*ceiling); P_AddThinker(THINK_MAIN, &ceiling->thinker); sec->ceilingdata = ceiling; diff --git a/src/p_floor.c b/src/p_floor.c index 9d0c6d816..6f425d7d1 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1618,7 +1618,9 @@ static floormove_t *CreateFloorThinker(sector_t *sec) return NULL; } - dofloor = Z_Calloc(sizeof (*dofloor), PU_LEVSPEC, NULL); + dofloor = Z_LevelPoolCalloc(sizeof(*dofloor)); + dofloor->thinker.alloctype = TAT_LEVELPOOL; + dofloor->thinker.size = sizeof(*dofloor); P_AddThinker(THINK_MAIN, &dofloor->thinker); // make sure another floor thinker won't get started over this one @@ -1911,7 +1913,9 @@ static elevator_t *CreateElevatorThinker(sector_t *sec) return NULL; } - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); + elevator = Z_LevelPoolCalloc(sizeof(*elevator)); + elevator->thinker.alloctype = TAT_LEVELPOOL; + elevator->thinker.size = sizeof(*elevator); P_AddThinker(THINK_MAIN, &elevator->thinker); // make sure other thinkers won't get started over this one @@ -2211,7 +2215,9 @@ void EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) if (sec->ceilingdata) // One at a time, ma'am. return; - bouncer = Z_Calloc(sizeof (*bouncer), PU_LEVSPEC, NULL); + bouncer = Z_LevelPoolCalloc(sizeof(*bouncer)); + bouncer->thinker.alloctype = TAT_LEVELPOOL; + bouncer->thinker.size = sizeof(*bouncer); P_AddThinker(THINK_MAIN, &bouncer->thinker); sec->ceilingdata = bouncer; bouncer->thinker.function.acp1 = (actionf_p1)T_BounceCheese; @@ -2238,7 +2244,9 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole backsector = sec; // create and initialize new thinker - faller = Z_Calloc(sizeof (*faller), PU_LEVSPEC, NULL); + faller = Z_LevelPoolCalloc(sizeof(*faller)); + faller->thinker.alloctype = TAT_LEVELPOOL; + faller->thinker.size = sizeof(*faller); P_AddThinker(THINK_MAIN, &faller->thinker); faller->thinker.function.acp1 = (actionf_p1)T_ContinuousFalling; @@ -2274,7 +2282,9 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, return 0; // create and initialize new crumble thinker - crumble = Z_Calloc(sizeof (*crumble), PU_LEVSPEC, NULL); + crumble = Z_LevelPoolCalloc(sizeof(*crumble)); + crumble->thinker.alloctype = TAT_LEVELPOOL; + crumble->thinker.size = sizeof(*crumble); P_AddThinker(THINK_MAIN, &crumble->thinker); crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble; @@ -2346,7 +2356,9 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) { // create and initialize new elevator thinker - block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); + block = Z_LevelPoolCalloc(sizeof(*block)); + block->thinker.alloctype = TAT_LEVELPOOL; + block->thinker.size = sizeof(*block); P_AddThinker(THINK_MAIN, &block->thinker); roversec->floordata = block; roversec->ceilingdata = block; diff --git a/src/p_lights.c b/src/p_lights.c index c46964c86..d5f58ebbc 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -75,7 +75,9 @@ fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *sector, INT16 lighta, INT1 fireflicker_t *flick; P_RemoveLighting(sector); // out with the old, in with the new - flick = Z_Calloc(sizeof (*flick), PU_LEVSPEC, NULL); + flick = Z_LevelPoolCalloc(sizeof(*flick)); + flick->thinker.alloctype = TAT_LEVELPOOL; + flick->thinker.size = sizeof(*flick); P_AddThinker(THINK_MAIN, &flick->thinker); @@ -150,7 +152,9 @@ void P_SpawnLightningFlash(sector_t *sector) sector->lightingdata = NULL; - flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + flash = Z_LevelPoolCalloc(sizeof(*flash)); + flash->thinker.alloctype = TAT_LEVELPOOL; + flash->thinker.size = sizeof(*flash); P_AddThinker(THINK_MAIN, &flash->thinker); @@ -209,7 +213,9 @@ strobe_t *P_SpawnAdjustableStrobeFlash(sector_t *sector, INT16 lighta, INT16 lig strobe_t *flash; P_RemoveLighting(sector); // out with the old, in with the new - flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + flash = Z_LevelPoolCalloc(sizeof(*flash)); + flash->thinker.alloctype = TAT_LEVELPOOL; + flash->thinker.size = sizeof(*flash); P_AddThinker(THINK_MAIN, &flash->thinker); @@ -279,7 +285,9 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *sector, INT16 lighta, INT16 ligh glow_t *g; P_RemoveLighting(sector); // out with the old, in with the new - g = Z_Calloc(sizeof (*g), PU_LEVSPEC, NULL); + g = Z_LevelPoolCalloc(sizeof(*g)); + g->thinker.alloctype = TAT_LEVELPOOL; + g->thinker.size = sizeof(*g); P_AddThinker(THINK_MAIN, &g->thinker); @@ -333,7 +341,9 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean return; } - ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL); + ll = Z_LevelPoolCalloc(sizeof(*ll)); + ll->thinker.alloctype = TAT_LEVELPOOL; + ll->thinker.size = sizeof(*ll); ll->thinker.function.acp1 = (actionf_p1)T_LightFade; sector->lightingdata = ll; // set it to the lightlevel_t diff --git a/src/p_local.h b/src/p_local.h index e886ef695..11385d656 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -78,7 +78,6 @@ typedef enum NUM_THINKERLISTS } thinklistnum_t; /**< Thinker lists. */ extern thinker_t thlist[]; -extern mobj_t *mobjcache; void P_InitThinkers(void); void P_InvalidateThinkersWithoutInit(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6a48a661c..e1e4a914b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12,6 +12,7 @@ /// \file p_mobj.c /// \brief Moving object handling. Spawn functions +#include "d_think.h" #include "dehacked.h" #include "doomdef.h" #include "g_game.h" @@ -64,8 +65,6 @@ mobj_t *waypointcap = NULL; // general purpose. mobj_t *trackercap = NULL; -mobj_t *mobjcache = NULL; - void P_InitCachedActions(void) { actioncachehead.prev = actioncachehead.next = &actioncachehead; @@ -1682,7 +1681,7 @@ boolean P_XYMovement(mobj_t *mo) predictedz = mo->z + slopemom.z; else predictedz = mo->z; - + } } else if (P_IsObjectOnGround(mo) && !mo->momz) predictedz = mo->z; @@ -1931,7 +1930,7 @@ boolean P_XYMovement(mobj_t *mo) // ); } } - else + else { // if (mo->player) // CONS_Printf("Ramp Launch %d %d+%d > 0 && %d-%d > %d ", mo->scale, FixedDiv(slopemom.z, mo->scale), P_GetMobjGravity(mo)*24, predictedz, mo->z, slopemom.z/2); @@ -2833,7 +2832,7 @@ void P_PlayerZMovement(mobj_t *mo) // CONS_Printf(" True\n"); mo->momz = 0; } - // else + // else // { // CONS_Printf(" False\n"); // } @@ -8423,7 +8422,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + mobj->target->height/2); // Taken from K_FlipFromObject. We just want to flip the visual according to its target, but that's it. mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP); - + break; } case MT_BUBBLESHIELD: @@ -8529,7 +8528,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->extravalue2 = mobj->target->player->bubbleblowup; P_SetScale(mobj, (mobj->destscale = scale)); - + // For some weird reason, the Bubble Shield is the exception flip-wise, it has the offset baked into the sprite. // So instead of simply flipping the object, we have to do a position offset. fixed_t positionOffset = 0; @@ -9031,7 +9030,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { cur->skin = &skins[newplayer->skin]; cur->color = newplayer->skincolor; - + // Even if we didn't have the Perfect Sign to consider, // it's still necessary to refresh SPR2 on skin changes. P_SetMobjState(cur, (newperfect == true) ? S_KART_SIGL : S_KART_SIGN); @@ -10846,19 +10845,9 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) mobj_t *P_AllocateMobj(void) { - mobj_t *mobj; - - if (mobjcache != NULL) - { - mobj = mobjcache; - mobjcache = mobjcache->hnext; - memset(mobj, 0, sizeof(*mobj)); - } - else - { - mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); - } - + mobj_t* mobj = (mobj_t*)Z_LevelPoolCalloc(sizeof(mobj_t)); + mobj->thinker.alloctype = TAT_LEVELPOOL; + mobj->thinker.size = sizeof(mobj_t); return mobj; } @@ -11375,7 +11364,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype const mobjinfo_t *info = &mobjinfo[type]; state_t *st; fixed_t start_z = INT32_MIN; - precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); + precipmobj_t *mobj = Z_LevelPoolCalloc(sizeof(precipmobj_t)); + mobj->thinker.alloctype = TAT_LEVELPOOL; + mobj->thinker.size = sizeof(precipmobj_t); mobj->type = type; mobj->info = info; @@ -11657,13 +11648,6 @@ void P_RemoveMobj(mobj_t *mobj) if (!mobj->thinker.next) { // Uh-oh, the mobj doesn't think, P_RemoveThinker would never go through! INT32 prevreferences; - if (!mobj->thinker.references) - { - // no references, dump it directly in the mobj cache - mobj->hnext = mobjcache; - mobjcache = mobj; - return; - } prevreferences = mobj->thinker.references; P_AddThinker(THINK_MOBJ, (thinker_t *)mobj); @@ -12263,7 +12247,7 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(aring, p->mo->scale); K_MatchGenericExtraFlags(aring, p->mo); aring->renderflags |= RF_DONTDRAW; - + mobj_t *abody = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_AMPBODY); P_SetTarget(&abody->target, p->mo); P_SetScale(abody, p->mo->scale); diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 82eb95432..891ed603e 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1995,7 +1995,9 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) return false; // create a new thinker - th = Z_Malloc(sizeof(polyrotate_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polyrotate_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polyrotate_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotate; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2067,7 +2069,9 @@ boolean EV_DoPolyObjMove(polymovedata_t *pmdata) return false; // create a new thinker - th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polymove_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polymove_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjMove; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2129,7 +2133,9 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) return false; // create a new thinker - th = Z_Malloc(sizeof(polywaypoint_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polywaypoint_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polywaypoint_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjWaypoint; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2197,7 +2203,9 @@ static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata) INT32 start; // allocate and add a new slide door thinker - th = Z_Malloc(sizeof(polyslidedoor_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polyslidedoor_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polyslidedoor_t); th->thinker.function.acp1 = (actionf_p1)T_PolyDoorSlide; P_AddThinker(THINK_POLYOBJ, &th->thinker); @@ -2248,7 +2256,9 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata) INT32 start; // allocate and add a new swing door thinker - th = Z_Malloc(sizeof(polyswingdoor_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polyswingdoor_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polyswingdoor_t); th->thinker.function.acp1 = (actionf_p1)T_PolyDoorSwing; P_AddThinker(THINK_POLYOBJ, &th->thinker); @@ -2333,7 +2343,9 @@ boolean EV_DoPolyObjDisplace(polydisplacedata_t *prdata) return false; // create a new thinker - th = Z_Malloc(sizeof(polydisplace_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polydisplace_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polydisplace_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjDisplace; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2382,7 +2394,9 @@ boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) return false; // create a new thinker - th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polyrotdisplace_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polyrotdisplace_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotDisplace; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2483,7 +2497,9 @@ boolean EV_DoPolyObjFlag(polyflagdata_t *pfdata) } // create a new thinker - th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polymove_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polymove_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjFlag; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2632,7 +2648,9 @@ boolean EV_DoPolyObjFade(polyfadedata_t *pfdata) P_RemoveThinker(po->thinker); // create a new thinker - th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL); + th = Z_LevelPoolMalloc(sizeof(polyfade_t)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(polyfade_t); th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a35f15061..83e31190c 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -12,6 +12,7 @@ /// \file p_saveg.cpp /// \brief Archiving: SaveGame I/O +#include "d_think.h" #include "doomdef.h" #include "byteptr.h" #include "d_main.h" @@ -4928,7 +4929,9 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadNoEnemiesThinker(savebuffer_t *save, actionf_p1 thinker) { - noenemies_t *ht = (noenemies_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + noenemies_t *ht = (noenemies_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); return &ht->thinker; @@ -4936,7 +4939,9 @@ static thinker_t* LoadNoEnemiesThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadBounceCheeseThinker(savebuffer_t *save, actionf_p1 thinker) { - bouncecheese_t *ht = (bouncecheese_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + bouncecheese_t *ht = (bouncecheese_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); ht->sector = LoadSector(READUINT32(save->p)); @@ -4954,7 +4959,9 @@ static thinker_t* LoadBounceCheeseThinker(savebuffer_t *save, actionf_p1 thinker static thinker_t* LoadContinuousFallThinker(savebuffer_t *save, actionf_p1 thinker) { - continuousfall_t *ht = (continuousfall_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + continuousfall_t *ht = (continuousfall_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->speed = READFIXED(save->p); @@ -4974,7 +4981,9 @@ static thinker_t* LoadContinuousFallThinker(savebuffer_t *save, actionf_p1 think static thinker_t* LoadMarioBlockThinker(savebuffer_t *save, actionf_p1 thinker) { - mariothink_t *ht = (mariothink_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + mariothink_t *ht = (mariothink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->speed = READFIXED(save->p); @@ -4994,7 +5003,9 @@ static thinker_t* LoadMarioBlockThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadMarioCheckThinker(savebuffer_t *save, actionf_p1 thinker) { - mariocheck_t *ht = (mariocheck_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + mariocheck_t *ht = (mariocheck_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); ht->sector = LoadSector(READUINT32(save->p)); @@ -5003,7 +5014,9 @@ static thinker_t* LoadMarioCheckThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadThwompThinker(savebuffer_t *save, actionf_p1 thinker) { - thwomp_t *ht = (thwomp_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + thwomp_t *ht = (thwomp_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); ht->sector = LoadSector(READUINT32(save->p)); @@ -5027,7 +5040,9 @@ static thinker_t* LoadThwompThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadFloatThinker(savebuffer_t *save, actionf_p1 thinker) { - floatthink_t *ht = (floatthink_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + floatthink_t *ht = (floatthink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); ht->sector = LoadSector(READUINT32(save->p)); @@ -5038,7 +5053,9 @@ static thinker_t* LoadFloatThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadEachTimeThinker(savebuffer_t *save, actionf_p1 thinker) { size_t i; - eachtime_t *ht = (eachtime_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + eachtime_t *ht = (eachtime_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); for (i = 0; i < MAXPLAYERS; i++) @@ -5051,7 +5068,9 @@ static thinker_t* LoadEachTimeThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadRaiseThinker(savebuffer_t *save, actionf_p1 thinker) { - raise_t *ht = (raise_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + raise_t *ht = (raise_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->tag = READINT16(save->p); ht->sector = LoadSector(READUINT32(save->p)); @@ -5066,7 +5085,9 @@ static thinker_t* LoadRaiseThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadCeilingThinker(savebuffer_t *save, actionf_p1 thinker) { - ceiling_t *ht = (ceiling_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ceiling_t *ht = (ceiling_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->type = (ceiling_e)READUINT8(save->p); ht->sector = LoadSector(READUINT32(save->p)); @@ -5091,7 +5112,9 @@ static thinker_t* LoadCeilingThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadFloormoveThinker(savebuffer_t *save, actionf_p1 thinker) { - floormove_t *ht = (floormove_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + floormove_t *ht = (floormove_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->type = (floor_e)READUINT8(save->p); ht->crush = READUINT8(save->p); @@ -5115,7 +5138,9 @@ static thinker_t* LoadFloormoveThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadLightflashThinker(savebuffer_t *save, actionf_p1 thinker) { - lightflash_t *ht = (lightflash_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + lightflash_t *ht = (lightflash_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->maxlight = READINT32(save->p); @@ -5127,7 +5152,9 @@ static thinker_t* LoadLightflashThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadStrobeThinker(savebuffer_t *save, actionf_p1 thinker) { - strobe_t *ht = (strobe_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + strobe_t *ht = (strobe_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->count = READINT32(save->p); @@ -5142,7 +5169,9 @@ static thinker_t* LoadStrobeThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadGlowThinker(savebuffer_t *save, actionf_p1 thinker) { - glow_t *ht = (glow_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + glow_t *ht = (glow_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->minlight = READINT16(save->p); @@ -5156,7 +5185,9 @@ static thinker_t* LoadGlowThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadFireflickerThinker(savebuffer_t *save, actionf_p1 thinker) { - fireflicker_t *ht = (fireflicker_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + fireflicker_t *ht = (fireflicker_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->count = READINT32(save->p); @@ -5170,7 +5201,9 @@ static thinker_t* LoadFireflickerThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, boolean setplanedata) { - elevator_t *ht = (elevator_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + elevator_t *ht = (elevator_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->type = (elevator_e)READUINT8(save->p); ht->sector = LoadSector(READUINT32(save->p)); @@ -5199,7 +5232,9 @@ static thinker_t* LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, bo static thinker_t* LoadCrumbleThinker(savebuffer_t *save, actionf_p1 thinker) { - crumble_t *ht = (crumble_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + crumble_t *ht = (crumble_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save->p)); ht->sector = LoadSector(READUINT32(save->p)); @@ -5221,7 +5256,9 @@ static thinker_t* LoadCrumbleThinker(savebuffer_t *save, actionf_p1 thinker) static thinker_t* LoadScrollThinker(savebuffer_t *save, actionf_p1 thinker) { - scroll_t *ht = (scroll_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + scroll_t *ht = (scroll_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->dx = READFIXED(save->p); ht->dy = READFIXED(save->p); @@ -5238,7 +5275,9 @@ static thinker_t* LoadScrollThinker(savebuffer_t *save, actionf_p1 thinker) static inline thinker_t* LoadFrictionThinker(savebuffer_t *save, actionf_p1 thinker) { - friction_t *ht = (friction_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + friction_t *ht = (friction_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->friction = READINT32(save->p); ht->movefactor = READINT32(save->p); @@ -5250,7 +5289,9 @@ static inline thinker_t* LoadFrictionThinker(savebuffer_t *save, actionf_p1 thin static thinker_t* LoadPusherThinker(savebuffer_t *save, actionf_p1 thinker) { - pusher_t *ht = (pusher_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + pusher_t *ht = (pusher_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->type = (pushertype_e)READUINT8(save->p); ht->x_mag = READFIXED(save->p); @@ -5266,7 +5307,9 @@ static thinker_t* LoadPusherThinker(savebuffer_t *save, actionf_p1 thinker) static inline thinker_t* LoadLaserThinker(savebuffer_t *save, actionf_p1 thinker) { - laserthink_t *ht = (laserthink_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + laserthink_t *ht = (laserthink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->tag = READINT16(save->p); ht->sourceline = LoadLine(READUINT32(save->p)); @@ -5276,7 +5319,9 @@ static inline thinker_t* LoadLaserThinker(savebuffer_t *save, actionf_p1 thinker static inline thinker_t* LoadLightlevelThinker(savebuffer_t *save, actionf_p1 thinker) { - lightlevel_t *ht = (lightlevel_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + lightlevel_t *ht = (lightlevel_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->sourcelevel = READINT16(save->p); @@ -5291,7 +5336,9 @@ static inline thinker_t* LoadLightlevelThinker(savebuffer_t *save, actionf_p1 th static inline thinker_t* LoadExecutorThinker(savebuffer_t *save, actionf_p1 thinker) { - executor_t *ht = (executor_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + executor_t *ht = (executor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->line = LoadLine(READUINT32(save->p)); ht->caller = LoadMobj(READUINT32(save->p)); @@ -5302,7 +5349,9 @@ static inline thinker_t* LoadExecutorThinker(savebuffer_t *save, actionf_p1 thin static inline thinker_t* LoadDisappearThinker(savebuffer_t *save, actionf_p1 thinker) { - disappear_t *ht = (disappear_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + disappear_t *ht = (disappear_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->appeartime = READUINT32(save->p); ht->disappeartime = READUINT32(save->p); @@ -5317,7 +5366,9 @@ static inline thinker_t* LoadDisappearThinker(savebuffer_t *save, actionf_p1 thi static inline thinker_t* LoadFadeThinker(savebuffer_t *save, actionf_p1 thinker) { sector_t *ss; - fade_t *ht = (fade_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + fade_t *ht = (fade_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->dest_exc = GetNetColormapFromList(READUINT32(save->p)); ht->sectornum = READUINT32(save->p); @@ -5358,7 +5409,9 @@ static inline thinker_t* LoadFadeThinker(savebuffer_t *save, actionf_p1 thinker) static inline thinker_t* LoadFadeColormapThinker(savebuffer_t *save, actionf_p1 thinker) { - fadecolormap_t *ht = (fadecolormap_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + fadecolormap_t *ht = (fadecolormap_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->sector = LoadSector(READUINT32(save->p)); ht->source_exc = GetNetColormapFromList(READUINT32(save->p)); @@ -5373,7 +5426,9 @@ static inline thinker_t* LoadFadeColormapThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadPlaneDisplaceThinker(savebuffer_t *save, actionf_p1 thinker) { - planedisplace_t *ht = (planedisplace_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + planedisplace_t *ht = (planedisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->affectee = READINT32(save->p); @@ -5386,7 +5441,9 @@ static inline thinker_t* LoadPlaneDisplaceThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadDynamicLineSlopeThinker(savebuffer_t *save, actionf_p1 thinker) { - dynlineplanethink_t* ht = (dynlineplanethink_t*)Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); + dynlineplanethink_t* ht = (dynlineplanethink_t*)Z_LevelPoolMalloc(sizeof(*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->type = (dynplanetype_t)READUINT8(save->p); @@ -5399,7 +5456,9 @@ static inline thinker_t* LoadDynamicLineSlopeThinker(savebuffer_t *save, actionf static inline thinker_t* LoadDynamicVertexSlopeThinker(savebuffer_t *save, actionf_p1 thinker) { size_t i; - dynvertexplanethink_t* ht = (dynvertexplanethink_t*)Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); + dynvertexplanethink_t* ht = (dynvertexplanethink_t*)Z_LevelPoolMalloc(sizeof(*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->slope = LoadSlope(READUINT32(save->p)); @@ -5414,7 +5473,9 @@ static inline thinker_t* LoadDynamicVertexSlopeThinker(savebuffer_t *save, actio static inline thinker_t* LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker) { - polyrotate_t *ht = (polyrotate_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polyrotate_t *ht = (polyrotate_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->speed = READINT32(save->p); @@ -5425,7 +5486,9 @@ static inline thinker_t* LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 t static thinker_t* LoadPolymoveThinker(savebuffer_t *save, actionf_p1 thinker) { - polymove_t *ht = (polymove_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polymove_t *ht = (polymove_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->speed = READINT32(save->p); @@ -5438,7 +5501,9 @@ static thinker_t* LoadPolymoveThinker(savebuffer_t *save, actionf_p1 thinker) static inline thinker_t* LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinker) { - polywaypoint_t *ht = (polywaypoint_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polywaypoint_t *ht = (polywaypoint_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->speed = READINT32(save->p); @@ -5453,7 +5518,9 @@ static inline thinker_t* LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 thinker) { - polyslidedoor_t *ht = (polyslidedoor_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polyslidedoor_t *ht = (polyslidedoor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->delay = READINT32(save->p); @@ -5473,7 +5540,9 @@ static inline thinker_t* LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 thinker) { - polyswingdoor_t *ht = (polyswingdoor_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polyswingdoor_t *ht = (polyswingdoor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->delay = READINT32(save->p); @@ -5488,7 +5557,9 @@ static inline thinker_t* LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinker) { - polydisplace_t *ht = (polydisplace_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polydisplace_t *ht = (polydisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->controlSector = LoadSector(READUINT32(save->p)); @@ -5500,7 +5571,9 @@ static inline thinker_t* LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 static inline thinker_t* LoadPolyrotdisplaceThinker(savebuffer_t *save, actionf_p1 thinker) { - polyrotdisplace_t *ht = (polyrotdisplace_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polyrotdisplace_t *ht = (polyrotdisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->controlSector = LoadSector(READUINT32(save->p)); @@ -5512,7 +5585,9 @@ static inline thinker_t* LoadPolyrotdisplaceThinker(savebuffer_t *save, actionf_ static thinker_t* LoadPolyfadeThinker(savebuffer_t *save, actionf_p1 thinker) { - polyfade_t *ht = (polyfade_t*)Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + polyfade_t *ht = (polyfade_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function.acp1 = thinker; ht->polyObjNum = READINT32(save->p); ht->sourcevalue = READINT32(save->p); @@ -5563,7 +5638,14 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) { (next->prev = currentthinker->prev)->next = next; R_DestroyLevelInterpolators(currentthinker); - Z_Free(currentthinker); + if (currentthinker->alloctype == TAT_LEVELPOOL) + { + Z_LevelPoolFree(currentthinker, currentthinker->size); + } + else + { + Z_Free(currentthinker); + } } } } @@ -6876,7 +6958,7 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) spawnss->tags.count * sizeof(mtag_t) ) ); - + } else { @@ -6966,7 +7048,7 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) spawnli->tags.count * sizeof(mtag_t) ) ); - + } else { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c8ed9cd95..8895b21db 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -8683,7 +8683,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) Patch_FreeTag(PU_PATCH_LOWPRIORITY); Patch_FreeTag(PU_PATCH_ROTATED); Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); - mobjcache = NULL; R_InitializeLevelInterpolators(); diff --git a/src/p_slopes.c b/src/p_slopes.c index f13c60d7b..3b42c5e73 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -11,6 +11,7 @@ /// \file p_slopes.c /// \brief ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron +#include "d_think.h" #include "doomdef.h" #include "r_defs.h" #include "r_state.h" @@ -300,7 +301,9 @@ void T_DynamicSlopeVert (dynvertexplanethink_t* th) static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent) { - dynlineplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); + dynlineplanethink_t* th = Z_LevelPoolCalloc(sizeof (*th)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(*th); th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeLine; th->slope = slope; th->type = type; @@ -314,7 +317,9 @@ static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t typ static inline void P_AddDynVertexSlopeThinker (pslope_t* slope, const INT16 tags[3], const vector3_t vx[3]) { - dynvertexplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL); + dynvertexplanethink_t* th = Z_LevelPoolCalloc(sizeof (*th)); + th->thinker.alloctype = TAT_LEVELPOOL; + th->thinker.size = sizeof(*th); size_t i; INT32 l; th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert; @@ -1091,7 +1096,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) vector3_t mom; // Ditto. if (P_CanApplySlopePhysics(thing, slope) == false) // No physics, no need to make anything complicated. - { + { if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; @@ -1151,7 +1156,7 @@ void P_ButteredSlope(mobj_t *mo) { // Allow the player to stand still on slopes below a certain steepness. // 45 degree angle steep, to be exact. - return; + return; } } diff --git a/src/p_spec.c b/src/p_spec.c index 9aec8ed53..4075e2f53 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -16,6 +16,7 @@ /// utility functions, etc. /// Line Tag handling. Line and Sector triggers. +#include "d_think.h" #include "dehacked.h" #include "doomdef.h" #include "g_game.h" @@ -1297,7 +1298,9 @@ static void P_AddExecutorDelay(line_t *line, mobj_t *mobj, sector_t *sector) delay = (line->backsector->ceilingheight >> FRACBITS) + (line->backsector->floorheight >> FRACBITS); } - e = Z_Calloc(sizeof (*e), PU_LEVSPEC, NULL); + e = Z_LevelPoolCalloc(sizeof (*e)); + e->thinker.alloctype = TAT_LEVELPOOL; + e->thinker.size = sizeof (*e); e->thinker.function.acp1 = (actionf_p1)T_ExecutorDelay; e->line = line; @@ -6393,7 +6396,9 @@ static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline) floatthink_t *floater; // create and initialize new thinker - floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL); + floater = Z_LevelPoolCalloc(sizeof (*floater)); + floater->thinker.alloctype = TAT_LEVELPOOL; + floater->thinker.size = sizeof (*floater); P_AddThinker(THINK_MAIN, &floater->thinker); floater->thinker.function.acp1 = (actionf_p1)T_FloatSector; @@ -6424,7 +6429,9 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, planedisplace_t *displace; // create and initialize new displacement thinker - displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL); + displace = Z_LevelPoolCalloc(sizeof (*displace)); + displace->thinker.alloctype = TAT_LEVELPOOL; + displace->thinker.size = sizeof (*displace); P_AddThinker(THINK_MAIN, &displace->thinker); displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace; @@ -6454,7 +6461,9 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) mariocheck_t *block; // create and initialize new elevator thinker - block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); + block = Z_LevelPoolCalloc(sizeof (*block)); + block->thinker.alloctype = TAT_LEVELPOOL; + block->thinker.size = sizeof (*block); P_AddThinker(THINK_MAIN, &block->thinker); block->thinker.function.acp1 = (actionf_p1)T_MarioBlockChecker; @@ -6479,7 +6488,9 @@ static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t c { raise_t *raise; - raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL); + raise = Z_LevelPoolCalloc(sizeof (*raise)); + raise->thinker.alloctype = TAT_LEVELPOOL; + raise->thinker.size = sizeof (*raise); P_AddThinker(THINK_MAIN, &raise->thinker); raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; @@ -6506,7 +6517,9 @@ static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, b { raise_t *airbob; - airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL); + airbob = Z_LevelPoolCalloc(sizeof (*airbob)); + airbob->thinker.alloctype = TAT_LEVELPOOL; + airbob->thinker.size = sizeof (*airbob); P_AddThinker(THINK_MAIN, &airbob->thinker); airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; @@ -6548,7 +6561,9 @@ static inline void P_AddThwompThinker(sector_t *sec, line_t *sourceline, fixed_t return; // create and initialize new elevator thinker - thwomp = Z_Calloc(sizeof (*thwomp), PU_LEVSPEC, NULL); + thwomp = Z_LevelPoolCalloc(sizeof (*thwomp)); + thwomp->thinker.alloctype = TAT_LEVELPOOL; + thwomp->thinker.size = sizeof (*thwomp); P_AddThinker(THINK_MAIN, &thwomp->thinker); thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector; @@ -6588,7 +6603,9 @@ static inline void P_AddNoEnemiesThinker(line_t *sourceline) noenemies_t *nobaddies; // create and initialize new thinker - nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL); + nobaddies = Z_LevelPoolCalloc(sizeof (*nobaddies)); + nobaddies->thinker.alloctype = TAT_LEVELPOOL; + nobaddies->thinker.size = sizeof (*nobaddies); P_AddThinker(THINK_MAIN, &nobaddies->thinker); nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector; @@ -6608,7 +6625,9 @@ static void P_AddEachTimeThinker(line_t *sourceline, boolean triggerOnExit) eachtime_t *eachtime; // create and initialize new thinker - eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL); + eachtime = Z_LevelPoolCalloc(sizeof (*eachtime)); + eachtime->thinker.alloctype = TAT_LEVELPOOL; + eachtime->thinker.size = sizeof (*eachtime); P_AddThinker(THINK_MAIN, &eachtime->thinker); eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker; @@ -6632,7 +6651,9 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n")); // create and initialize new elevator thinker - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); + elevator = Z_LevelPoolCalloc(sizeof (*elevator)); + elevator->thinker.alloctype = TAT_LEVELPOOL; + elevator->thinker.size = sizeof (*elevator); P_AddThinker(THINK_MAIN, &elevator->thinker); elevator->thinker.function.acp1 = (actionf_p1)T_CameraScanner; @@ -6713,7 +6734,9 @@ void T_LaserFlash(laserthink_t *flash) static inline void P_AddLaserThinker(INT16 tag, line_t *line, boolean nobosses) { - laserthink_t *flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + laserthink_t *flash = Z_LevelPoolCalloc(sizeof (*flash)); + flash->thinker.alloctype = TAT_LEVELPOOL; + flash->thinker.size = sizeof (*flash); P_AddThinker(THINK_MAIN, &flash->thinker); @@ -8244,7 +8267,9 @@ void T_Scroll(scroll_t *s) */ static void Add_Scroller(INT32 type, fixed_t dx, fixed_t dy, INT32 control, INT32 affectee, INT32 accel, INT32 exclusive) { - scroll_t *s = Z_Calloc(sizeof *s, PU_LEVSPEC, NULL); + scroll_t *s = Z_LevelPoolCalloc(sizeof (*s)); + s->thinker.alloctype = TAT_LEVELPOOL; + s->thinker.size = sizeof (*s); s->thinker.function.acp1 = (actionf_p1)T_Scroll; s->type = type; s->dx = dx; @@ -8389,7 +8414,9 @@ static void P_SpawnScrollers(void) */ static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline) { - disappear_t *d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); + disappear_t *d = Z_LevelPoolCalloc(sizeof (*d)); + d->thinker.alloctype = TAT_LEVELPOOL; + d->thinker.size = sizeof (*d); d->thinker.function.acp1 = (actionf_p1)T_Disappear; d->appeartime = appeartime; @@ -8784,7 +8811,9 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor if (rover->alpha == max(1, min(256, relative ? rover->alpha + destvalue : destvalue))) return; - d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); + d = Z_LevelPoolCalloc(sizeof (*d)); + d->thinker.alloctype = TAT_LEVELPOOL; + d->thinker.size = sizeof (*d); d->thinker.function.acp1 = (actionf_p1)T_Fade; d->rover = rover; @@ -8937,7 +8966,9 @@ static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, ext return; } - d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL); + d = Z_LevelPoolCalloc(sizeof (*d)); + d->thinker.alloctype = TAT_LEVELPOOL; + d->thinker.size = sizeof (*d); d->thinker.function.acp1 = (actionf_p1)T_FadeColormap; d->sector = sector; d->source_exc = source_exc; @@ -9060,7 +9091,9 @@ void T_FadeColormap(fadecolormap_t *d) */ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer) { - friction_t *f = Z_Calloc(sizeof *f, PU_LEVSPEC, NULL); + friction_t *f = Z_LevelPoolCalloc(sizeof (*f)); + f->thinker.alloctype = TAT_LEVELPOOL; + f->thinker.size = sizeof (*f); f->thinker.function.acp1 = (actionf_p1)T_Friction; f->friction = friction; @@ -9194,7 +9227,9 @@ static void P_SpawnFriction(void) */ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, fixed_t z_mag, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider) { - pusher_t *p = Z_Calloc(sizeof *p, PU_LEVSPEC, NULL); + pusher_t *p = Z_LevelPoolCalloc(sizeof (*p)); + p->thinker.alloctype = TAT_LEVELPOOL; + p->thinker.size = sizeof (*p); p->thinker.function.acp1 = (actionf_p1)T_Pusher; p->type = type; diff --git a/src/p_tick.c b/src/p_tick.c index 0860abb21..2b635a0bd 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -12,6 +12,7 @@ /// \file p_tick.c /// \brief Archiving: SaveGame I/O, Thinker, Ticker +#include "d_think.h" #include "doomstat.h" #include "d_main.h" #include "g_game.h" @@ -330,7 +331,6 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker) thlist[n].prev = thinker; thinker->references = 0; // killough 11/98: init reference counter to 0 - thinker->cachable = n == THINK_MOBJ; #ifdef PARANOIA thinker->debug_mobjtype = MT_NULL; @@ -448,11 +448,9 @@ void P_UnlinkThinker(thinker_t *thinker) I_Assert(thinker->references == 0); (next->prev = thinker->prev)->next = next; - if (thinker->cachable) + if (thinker->alloctype == TAT_LEVELPOOL) { - // put cachable thinkers in the mobj cache, so we can avoid allocations - ((mobj_t *)thinker)->hnext = mobjcache; - mobjcache = (mobj_t *)thinker; + Z_LevelPoolFree(thinker, thinker->size); } else { diff --git a/src/z_zone.cpp b/src/z_zone.cpp index ed38cd277..1d80b8fc6 100644 --- a/src/z_zone.cpp +++ b/src/z_zone.cpp @@ -31,6 +31,7 @@ #include +#include "core/memory.h" #include "doomdef.h" #include "doomstat.h" #include "r_patch.h" @@ -53,7 +54,6 @@ static boolean Z_calloc = false; #define ZONEID 0xa441d13d - typedef struct memblock_s { void **user; @@ -76,6 +76,16 @@ typedef struct memblock_s // both the head and tail of the zone memory block list static memblock_t head; +static constexpr size_t kLevelLargePoolBlockSize = sizeof(mobj_t); +static constexpr size_t kLevelMedPoolBlockSize = sizeof(precipmobj_t); +static constexpr size_t kLevelSmallPoolBlockSize = 128; +static constexpr size_t kLevelTinyPoolBlockSize = 64; + +static srb2::PoolAllocator g_level_large_pool { kLevelLargePoolBlockSize, 1024, PU_LEVEL }; +static srb2::PoolAllocator g_level_med_pool { kLevelMedPoolBlockSize, 32768, PU_LEVEL }; +static srb2::PoolAllocator g_level_small_pool { kLevelSmallPoolBlockSize, 4096, PU_LEVEL }; +static srb2::PoolAllocator g_level_tiny_pool { kLevelTinyPoolBlockSize, 8192, PU_LEVEL }; + // // Function prototypes // @@ -355,6 +365,16 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) TracyCZone(__zone, true); Z_CheckHeap(420); + + // First, release all pools, since they can make allocations in zones. + if (PU_LEVEL >= lowtag && PU_LEVEL <= hightag) + { + g_level_large_pool.release(); + g_level_med_pool.release(); + g_level_small_pool.release(); + g_level_tiny_pool.release(); + } + for (block = head.next; block != &head; block = next) { next = block->next; // get link before freeing @@ -664,3 +684,59 @@ char *Z_StrDup(const char *s) { return strcpy((char*)ZZ_Alloc(strlen(s) + 1), s); } + +void* Z_LevelPoolMalloc(size_t size) +{ + void* p = nullptr; + if (size <= kLevelTinyPoolBlockSize) + { + p = g_level_tiny_pool.allocate(); + } + else if (size <= kLevelSmallPoolBlockSize) + { + p = g_level_small_pool.allocate(); + } + else if (size <= kLevelMedPoolBlockSize) + { + p = g_level_med_pool.allocate(); + } + else if (size <= kLevelLargePoolBlockSize) + { + p = g_level_large_pool.allocate(); + } + + if (p == nullptr) + { + p = Z_Malloc(size, PU_LEVEL, nullptr); + } + + return p; +} + +void* Z_LevelPoolCalloc(size_t size) +{ + void* p = Z_LevelPoolMalloc(size); + memset(p, 0, size); + return p; +} + +void Z_LevelPoolFree(void* p, size_t size) +{ + if (size <= kLevelTinyPoolBlockSize) + { + return g_level_tiny_pool.deallocate(p); + } + if (size <= kLevelSmallPoolBlockSize) + { + return g_level_small_pool.deallocate(p); + } + if (size <= kLevelMedPoolBlockSize) + { + return g_level_med_pool.deallocate(p); + } + if (size <= kLevelLargePoolBlockSize) + { + return g_level_large_pool.deallocate(p); + } + return Z_Free(p); +} diff --git a/src/z_zone.h b/src/z_zone.h index 8bfb5f774..0e544134f 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -148,6 +148,13 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); #define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed +// +// Specialty allocation functions +// +void *Z_LevelPoolMalloc(size_t size); +void *Z_LevelPoolCalloc(size_t size); +void Z_LevelPoolFree(void *p, size_t size); + #ifdef __cplusplus } // extern "C" #endif