From b45de0b7ecd89b8493aea3eda7c0936b5b99eab5 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 2 Nov 2024 17:30:19 +0000 Subject: [PATCH] Merge branch 'slab-allocate-mobj' into 'master' Add level pool allocator and use it for mobj, precip, thinkers See merge request KartKrew/Kart!2482 --- src/Sourcefile | 2 +- src/core/memory.cpp | 82 +++++++++++++++++- 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 | 31 ++----- src/p_polyobj.c | 36 ++++++-- src/p_saveg.c | 157 ++++++++++++++++++++++++++--------- src/p_setup.c | 1 - src/p_slopes.c | 11 ++- src/p_spec.c | 69 +++++++++++---- src/p_tick.c | 8 +- src/{z_zone.c => z_zone.cpp} | 88 ++++++++++++++++++-- src/z_zone.h | 7 ++ 17 files changed, 490 insertions(+), 120 deletions(-) rename src/{z_zone.c => z_zone.cpp} (89%) diff --git a/src/Sourcefile b/src/Sourcefile index 67d8dfff1..192774079 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -10,7 +10,7 @@ dehacked.c deh_soc.c deh_lua.c deh_tables.c -z_zone.c +z_zone.cpp f_finale.c f_dscredits.cpp f_wipe.c diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e75cf91f7..219f64bba 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -10,10 +10,13 @@ #include "memory.h" -#include +#include + +#include "../cxxutil.hpp" +#include "../z_zone.h" #include -#include "../z_zone.h" +using namespace srb2; namespace { @@ -58,6 +61,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 ba49e3d51..d568d34e9 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 181745dd9..604b9e3bf 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -30,6 +30,15 @@ extern "C" { // typedef void (*actionf_p1)(void *); +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_p1 think_t; @@ -44,7 +53,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 cebb160e2..9f99eed3e 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -11,6 +11,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" @@ -460,7 +461,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; @@ -848,7 +851,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 43a64a78e..1a8bac488 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1816,7 +1816,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(mapnamespace == MNS_SRB2KART ? THINK_FLOORS : THINK_MAIN, &dofloor->thinker); // make sure another floor thinker won't get started over this one @@ -2109,7 +2111,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 @@ -2408,7 +2412,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 = (actionf_p1)T_BounceCheese; @@ -2435,7 +2441,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 = (actionf_p1)T_ContinuousFalling; @@ -2471,7 +2479,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 = (actionf_p1)T_StartCrumble; @@ -2545,7 +2555,9 @@ void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) const boolean itsamonitor = (thing->flags & MF_MONITOR) == MF_MONITOR; // 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 4935d2934..85a258218 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -74,7 +74,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); @@ -149,7 +151,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); @@ -208,7 +212,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); @@ -278,7 +284,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); @@ -332,7 +340,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 = (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 25299261f..4fdefb4e7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -83,7 +83,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 fc5b7fab5..51cbb1927 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13,6 +13,7 @@ #include "p_mobj.h" #include "d_netcmd.h" +#include "d_think.h" #include "dehacked.h" #include "doomdef.h" #include "doomstat.h" @@ -67,8 +68,6 @@ mobj_t *misccap = NULL; // Used for misc object tracking mobj_t *waypointcap = NULL; mobj_t *boss3cap = NULL; -mobj_t *mobjcache = NULL; - void P_InitCachedActions(void) { actioncachehead.prev = actioncachehead.next = &actioncachehead; @@ -9162,6 +9161,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->sloperoll = 0; P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + break; } case MT_BUBBLESHIELD: @@ -11066,19 +11066,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; } @@ -11630,7 +11620,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; @@ -11838,13 +11830,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); diff --git a/src/p_polyobj.c b/src/p_polyobj.c index f5f0305a6..bf6638708 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2029,7 +2029,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 = (actionf_p1)T_PolyObjRotate; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2101,7 +2103,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 = (actionf_p1)T_PolyObjMove; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2163,7 +2167,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 = (actionf_p1)T_PolyObjWaypoint; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2230,7 +2236,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 = (actionf_p1)T_PolyDoorSlide; P_AddThinker(THINK_POLYOBJ, &th->thinker); @@ -2281,7 +2289,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 = (actionf_p1)T_PolyDoorSwing; P_AddThinker(THINK_POLYOBJ, &th->thinker); @@ -2366,7 +2376,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 = (actionf_p1)T_PolyObjDisplace; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2415,7 +2427,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 = (actionf_p1)T_PolyObjRotDisplace; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2520,7 +2534,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 = (actionf_p1)T_PolyObjFlag; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; @@ -2673,7 +2689,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 = (actionf_p1)T_PolyObjFade; P_AddThinker(THINK_POLYOBJ, &th->thinker); po->thinker = &th->thinker; diff --git a/src/p_saveg.c b/src/p_saveg.c index 281e33a61..7c96b3ec2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2384,7 +2384,9 @@ static thinker_t *SyncNoEnemiesThinker(savebuffer_t *save, actionf_p1 thinker, t } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (noenemies_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } SYNC(ht->sourceline); @@ -2400,7 +2402,9 @@ static thinker_t *SyncBounceCheeseThinker(savebuffer_t *save, actionf_p1 thinker } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (bouncecheese_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2425,7 +2429,9 @@ static thinker_t *SyncContinuousFallThinker(savebuffer_t *save, actionf_p1 think } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (continuousfall_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2452,7 +2458,9 @@ static thinker_t *SyncMarioBlockThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (mariothink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2479,7 +2487,9 @@ static thinker_t *SyncMarioCheckThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (mariocheck_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2497,7 +2507,9 @@ static thinker_t *SyncThwompThinker(savebuffer_t *save, actionf_p1 thinker, thin } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (thwomp_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2529,7 +2541,9 @@ static thinker_t *SyncFloatThinker(savebuffer_t *save, actionf_p1 thinker, think } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (floatthink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2548,7 +2562,9 @@ static thinker_t *SyncEachTimeThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (eachtime_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2571,7 +2587,9 @@ static thinker_t *SyncRaiseThinker(savebuffer_t *save, actionf_p1 thinker, think } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (raise_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2595,7 +2613,9 @@ static thinker_t *SyncCeilingThinker(savebuffer_t *save, actionf_p1 thinker, thi } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (ceiling_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2631,7 +2651,9 @@ static thinker_t *SyncFloormoveThinker(savebuffer_t *save, actionf_p1 thinker, t } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (floormove_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2663,7 +2685,9 @@ static thinker_t *SyncLightflashThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (lightflash_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } SYNC(ht->sector); @@ -2683,7 +2707,9 @@ static thinker_t *SyncStrobeThinker(savebuffer_t *save, actionf_p1 thinker, thin } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (strobe_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2707,7 +2733,9 @@ static thinker_t *SyncGlowThinker(savebuffer_t *save, actionf_p1 thinker, thinke } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (glow_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2730,7 +2758,9 @@ static thinker_t *SyncFireflickerThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (fireflicker_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2754,7 +2784,9 @@ static thinker_t *SyncElevatorThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (elevator_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2791,7 +2823,9 @@ static thinker_t *SyncCrumbleThinker(savebuffer_t *save, actionf_p1 thinker, thi } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (crumble_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2822,7 +2856,9 @@ static thinker_t *SyncScrollThinker(savebuffer_t *save, actionf_p1 thinker, thin } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (scroll_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2848,7 +2884,9 @@ static thinker_t *SyncFrictionThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (friction_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2869,7 +2907,9 @@ static thinker_t *SyncPusherThinker(savebuffer_t *save, actionf_p1 thinker, thin } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (pusher_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2894,7 +2934,9 @@ static thinker_t *SyncLaserThinker(savebuffer_t *save, actionf_p1 thinker, think } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (laserthink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2913,7 +2955,9 @@ static thinker_t *SyncLightlevelThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (lightlevel_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2937,7 +2981,9 @@ static thinker_t *SyncExecutorThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (executor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2957,7 +3003,9 @@ static thinker_t *SyncDisappearThinker(savebuffer_t *save, actionf_p1 thinker, t } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (disappear_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -2980,7 +3028,9 @@ static thinker_t *SyncFadeThinker(savebuffer_t *save, actionf_p1 thinker, thinke } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (fade_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3033,7 +3083,9 @@ static thinker_t *SyncFadeColormapThinker(savebuffer_t *save, actionf_p1 thinker } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (fadecolormap_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3057,7 +3109,9 @@ static thinker_t *SyncPlaneDisplaceThinker(savebuffer_t *save, actionf_p1 thinke } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (planedisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3078,7 +3132,9 @@ static thinker_t *SyncDynamicLineSlopeThinker(savebuffer_t *save, actionf_p1 thi } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (dynlineplanethink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3099,7 +3155,9 @@ static thinker_t *SyncDynamicVertexSlopeThinker(savebuffer_t *save, actionf_p1 t } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (dynvertexplanethink_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3122,7 +3180,9 @@ static thinker_t *SyncPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker, } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polyrotate_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3142,7 +3202,9 @@ static thinker_t *SyncPolymoveThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polymove_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3164,7 +3226,9 @@ static thinker_t *SyncPolywaypointThinker(savebuffer_t *save, actionf_p1 thinker } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polywaypoint_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3188,7 +3252,9 @@ static thinker_t *SyncPolyslidedoorThinker(savebuffer_t *save, actionf_p1 thinke } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polyslidedoor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3217,7 +3283,9 @@ static thinker_t *SyncPolyswingdoorThinker(savebuffer_t *save, actionf_p1 thinke } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polyswingdoor_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3241,7 +3309,9 @@ static thinker_t *SyncPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinker } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polydisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3262,7 +3332,9 @@ static thinker_t *SyncPolyrotdisplaceThinker(savebuffer_t *save, actionf_p1 thin } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polyrotdisplace_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3283,7 +3355,9 @@ static thinker_t *SyncPolyfadeThinker(savebuffer_t *save, actionf_p1 thinker, th } else { - ht = Z_Calloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht = (polyfade_t*)Z_LevelPoolMalloc(sizeof (*ht)); + ht->thinker.alloctype = TAT_LEVELPOOL; + ht->thinker.size = sizeof (*ht); ht->thinker.function = thinker; } @@ -3391,7 +3465,14 @@ static void P_NetSyncThinkers(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); + } } } } diff --git a/src/p_setup.c b/src/p_setup.c index 043395cf2..f07634c7e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8757,7 +8757,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 1b93aafdc..e8f4b55ba 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -10,6 +10,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" @@ -304,7 +305,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 = (actionf_p1)T_DynamicSlopeLine; th->slope = slope; th->type = type; @@ -318,7 +321,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 = (actionf_p1)T_DynamicSlopeVert; @@ -1077,7 +1082,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; diff --git a/src/p_spec.c b/src/p_spec.c index c5e86ce28..dfb60edcc 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -15,6 +15,7 @@ /// utility functions, etc. /// Line Tag handling. Line and Sector triggers. +#include "d_think.h" #include "dehacked.h" #include "doomdef.h" #include "doomstat.h" @@ -1240,7 +1241,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 = (actionf_p1)T_ExecutorDelay; e->line = line; @@ -6452,7 +6455,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 = (actionf_p1)T_FloatSector; @@ -6483,7 +6488,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 = (actionf_p1)T_PlaneDisplace; @@ -6513,7 +6520,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 = (actionf_p1)T_MarioBlockChecker; @@ -6538,7 +6547,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 = (actionf_p1)T_RaiseSector; @@ -6564,7 +6575,9 @@ static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, b (void)spindash; 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 = (actionf_p1)T_RaiseSector; @@ -6604,7 +6617,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 = (actionf_p1)T_ThwompSector; @@ -6644,7 +6659,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 = (actionf_p1)T_NoEnemiesSector; @@ -6664,7 +6681,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 = (actionf_p1)T_EachTimeThinker; @@ -6688,7 +6707,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 = (actionf_p1)T_CameraScanner; @@ -6772,7 +6793,9 @@ void T_LaserFlash(void *thinker) 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); @@ -8333,7 +8356,9 @@ static boolean IsSector3DBlock(sector_t* sec) */ 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 = (actionf_p1)T_Scroll; s->type = type; s->dx = dx; @@ -8488,7 +8513,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 = (actionf_p1)T_Disappear; d->appeartime = appeartime; @@ -8884,7 +8911,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 = (actionf_p1)T_Fade; d->rover = rover; @@ -9038,7 +9067,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 = (actionf_p1)T_FadeColormap; d->sector = sector; d->source_exc = source_exc; @@ -9162,7 +9193,9 @@ void T_FadeColormap(void *thinker) */ 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 = (actionf_p1)T_Friction; f->friction = friction; @@ -9320,7 +9353,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 = (actionf_p1)T_Pusher; p->type = type; diff --git a/src/p_tick.c b/src/p_tick.c index d08fcce92..81032f3ad 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -11,6 +11,7 @@ /// \file p_tick.c /// \brief Archiving: SaveGame I/O, Thinker, Ticker +#include "d_think.h" #include "doomstat.h" #include "g_game.h" #include "g_input.h" @@ -253,7 +254,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; @@ -371,11 +371,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.c b/src/z_zone.cpp similarity index 89% rename from src/z_zone.c rename to src/z_zone.cpp index bf538910e..d06c1a8d4 100644 --- a/src/z_zone.c +++ b/src/z_zone.cpp @@ -30,6 +30,7 @@ //#include +#include "core/memory.h" #include "doomdef.h" #include "doomstat.h" #include "r_patch.h" @@ -52,7 +53,6 @@ static boolean Z_calloc = false; #define ZONEID 0xa441d13d - typedef struct memblock_s { void **user; @@ -75,6 +75,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 // @@ -212,7 +222,7 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif - block = xm(sizeof (memblock_t) + ALIGNPAD + size); + block = (memblock_t*)xm(sizeof (memblock_t) + ALIGNPAD + size); //TracyCAlloc(block, sizeof (memblock_t) + ALIGNPAD + size); ptr = MEMORY(block); I_Assert((intptr_t)ptr % alignof (max_align_t) == 0); @@ -238,7 +248,7 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, if (user != NULL) { - block->user = user; + block->user = (void**)user; *(void **)user = ptr; } else if (tag >= PU_PURGELEVEL) @@ -350,6 +360,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 @@ -544,7 +564,7 @@ void Z_SetUser(void *ptr, void **newuser) I_Error("Internal memory management error: " "tried to make block purgable but it has no owner"); - block->user = (void*)newuser; + block->user = (void**)newuser; *newuser = ptr; } @@ -639,7 +659,7 @@ static void Command_Memdump_f(void) for (block = head.next; block != &head; block = block->next) if (block->tag >= mintag && block->tag <= maxtag) { - char *filename = strrchr(block->ownerfile, PATHSEP[0]); + const char *filename = strrchr(block->ownerfile, PATHSEP[0]); CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline); } } @@ -651,5 +671,61 @@ static void Command_Memdump_f(void) */ char *Z_StrDup(const char *s) { - return strcpy(ZZ_Alloc(strlen(s) + 1), 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 361f10cf8..597a93547 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -158,6 +158,13 @@ FUNCINLINE static ATTRINLINE void pfree(void *p) free(*(void **)p); } +// +// 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