Merge branch 'slab-allocate-mobj' into 'master'

Add level pool allocator and use it for mobj, precip, thinkers

See merge request KartKrew/Kart!2482
This commit is contained in:
Eidolon 2024-11-02 17:30:19 +00:00 committed by NepDisk
parent ebfdfc86b4
commit b45de0b7ec
17 changed files with 490 additions and 120 deletions

View file

@ -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

View file

@ -10,10 +10,13 @@
#include "memory.h"
#include <array>
#include <cstdint>
#include "../cxxutil.hpp"
#include "../z_zone.h"
#include <new>
#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<FreeBlock*>(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)

View file

@ -14,6 +14,58 @@
#include <stddef.h>
#ifdef __cplusplus
#include <cstdint>
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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
}
}
}
}

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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
{

View file

@ -30,6 +30,7 @@
//#include <tracy/tracy/TracyC.h>
#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);
}

View file

@ -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