mirror of
https://github.com/thunderbrewhq/common.git
synced 2025-12-12 03:02:29 +00:00
feat(objectalloc): update ObjectAlloc methods to support freeing of memory
This commit is contained in:
parent
ab0b7965db
commit
94dcf8ca77
6 changed files with 81 additions and 12 deletions
|
|
@ -32,7 +32,7 @@ int32_t ObjectAlloc(uint32_t heapId, uint32_t* memHandle, void** objectPtr, bool
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool a4) {
|
||||
uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool freeEmptyHeaps) {
|
||||
STORM_ASSERT(objectSize > 0);
|
||||
|
||||
auto globals = GetObjAllocGlobals();
|
||||
|
|
@ -43,7 +43,7 @@ uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const ch
|
|||
heap->m_objSize = objectSize;
|
||||
heap->m_objsPerBlock = objsPerBlock;
|
||||
SStrCopy(heap->m_heapName, name, sizeof(heap->m_heapName));
|
||||
heap->char84 = a4;
|
||||
heap->m_freeEmptyHeaps = freeEmptyHeaps;
|
||||
|
||||
ReleaseObjAllocGlobals();
|
||||
|
||||
|
|
@ -61,3 +61,10 @@ uint32_t ObjectAllocUsage(uint32_t heapId) {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ObjectAllocDestroy() {
|
||||
// NOTICE: It seems like sub_4D2F90 does nothing useful
|
||||
auto globals = GetObjAllocGlobals();
|
||||
globals->objects.Clear();
|
||||
ReleaseObjAllocGlobals();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
int32_t ObjectAlloc(uint32_t heapId, uint32_t* memHandle, void** objectPtr, bool zero);
|
||||
|
||||
uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool a4);
|
||||
uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool freeEmptyHeaps);
|
||||
|
||||
uint32_t ObjectAllocUsage(uint32_t heapId);
|
||||
|
||||
void ObjectAllocDestroy();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ int32_t CObjectHeap::Allocate(uint32_t objSize, uint32_t heapObjects, const char
|
|||
|
||||
void* indexStack = static_cast<char*>(this->m_obj) + heapObjects * objSize;
|
||||
this->m_indexStack = reinterpret_cast<uint32_t*>(indexStack);
|
||||
this->m_bytes = heapObjects * objSize;
|
||||
|
||||
for (int32_t i = 0; i < heapObjects; i++) {
|
||||
this->m_indexStack[i] = i;
|
||||
|
|
@ -90,11 +89,6 @@ void* CObjectHeap::Ptr(uint32_t index, uint32_t objSize, uint32_t heapObjects) {
|
|||
bytes[3]);
|
||||
}
|
||||
|
||||
if (objSize * index >= this->m_bytes) {
|
||||
SErrPrepareAppFatal(__FILE__, __LINE__);
|
||||
SErrDisplayAppFatal("CObjectHeap::Ptr(): index(%u), objSize(%u), m_bytes(%u)", index, objSize, this->m_bytes);
|
||||
}
|
||||
|
||||
return static_cast<char*>(this->m_obj) + objSize * index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ class CObjectHeap {
|
|||
void* m_obj = nullptr;
|
||||
uint32_t* m_indexStack = nullptr;
|
||||
uint32_t m_allocated = 0;
|
||||
uint32_t m_bytes = 0;
|
||||
|
||||
// Member functions
|
||||
CObjectHeap() = default;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,71 @@ int32_t CObjectHeapList::New(uint32_t* index, void** obj, bool zero) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void CObjectHeapList::Delete(uint32_t index) {
|
||||
uint32_t heapId = index / this->m_objsPerBlock;
|
||||
uint32_t stackId = index % this->m_objsPerBlock;
|
||||
|
||||
auto& heap = this->m_heaps[heapId];
|
||||
if (heap.m_allocated == this->m_objsPerBlock) {
|
||||
this->m_numFullHeaps--;
|
||||
}
|
||||
|
||||
heap.Delete(stackId, this->m_objSize, this->m_objsPerBlock);
|
||||
|
||||
if (this->m_freeEmptyHeaps) {
|
||||
if (heap.m_obj && !heap.m_allocated) {
|
||||
this->m_hasEmptyHeaps = 1;
|
||||
}
|
||||
|
||||
if (this->m_hasEmptyHeaps) {
|
||||
bool freeHeaps = (((this->m_objsPerBlock - 1) >> 2) & this->uint20) == 0;
|
||||
this->uint20++;
|
||||
if (freeHeaps) {
|
||||
FreeEmptyHeaps();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectHeapList::FreeEmptyHeaps() {
|
||||
if (!this->m_heaps.Count()) {
|
||||
this->m_hasEmptyHeaps = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t totalAllocated = 0;
|
||||
uint32_t totalObjsPerBlock = 0;
|
||||
uint32_t totalEmptyHeaps = 0;
|
||||
|
||||
for (uint32_t i = 0; i < this->m_heaps.Count(); ++i) {
|
||||
auto& heap = this->m_heaps[i];
|
||||
if (heap.m_obj) {
|
||||
totalObjsPerBlock += this->m_objsPerBlock;
|
||||
if (heap.m_allocated) {
|
||||
totalAllocated += heap.m_allocated;
|
||||
} else {
|
||||
totalEmptyHeaps++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!totalEmptyHeaps) {
|
||||
this->m_hasEmptyHeaps = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
totalAllocated += ((3 * this->m_objsPerBlock) >> 1);
|
||||
|
||||
uint32_t count = this->m_heaps.Count();
|
||||
|
||||
while (count > 0 && totalAllocated < totalObjsPerBlock && !totalEmptyHeaps) {
|
||||
// TODO: Remove last element from this->m_heaps
|
||||
count--;
|
||||
}
|
||||
|
||||
this->m_hasEmptyHeaps = totalEmptyHeaps != 0;
|
||||
}
|
||||
|
||||
uint32_t CObjectHeapList::BlocksAllocated() {
|
||||
uint32_t result = 0;
|
||||
for (uint32_t i = 0; i < this->m_heaps.Count(); ++i) {
|
||||
|
|
|
|||
|
|
@ -11,17 +11,19 @@ class CObjectHeapList {
|
|||
uint32_t m_objSize = 0;
|
||||
uint32_t m_objsPerBlock = 128;
|
||||
uint32_t m_numFullHeaps = 0;
|
||||
uint32_t uint1C = 0;
|
||||
uint32_t m_hasEmptyHeaps = 0;
|
||||
uint32_t uint20 = 0;
|
||||
uint32_t m_fullestHeap = 0;
|
||||
char m_heapName[80];
|
||||
uint32_t uint78 = 0;
|
||||
uint32_t uint7C = 0;
|
||||
uint32_t uint80 = 0;
|
||||
uint8_t char84 = 1;
|
||||
uint8_t m_freeEmptyHeaps = 1;
|
||||
|
||||
// Member functions
|
||||
int32_t New(uint32_t* index, void** obj, bool zero);
|
||||
void Delete(uint32_t index);
|
||||
void FreeEmptyHeaps();
|
||||
uint32_t BlocksAllocated();
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue