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;
|
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);
|
STORM_ASSERT(objectSize > 0);
|
||||||
|
|
||||||
auto globals = GetObjAllocGlobals();
|
auto globals = GetObjAllocGlobals();
|
||||||
|
|
@ -43,7 +43,7 @@ uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const ch
|
||||||
heap->m_objSize = objectSize;
|
heap->m_objSize = objectSize;
|
||||||
heap->m_objsPerBlock = objsPerBlock;
|
heap->m_objsPerBlock = objsPerBlock;
|
||||||
SStrCopy(heap->m_heapName, name, sizeof(heap->m_heapName));
|
SStrCopy(heap->m_heapName, name, sizeof(heap->m_heapName));
|
||||||
heap->char84 = a4;
|
heap->m_freeEmptyHeaps = freeEmptyHeaps;
|
||||||
|
|
||||||
ReleaseObjAllocGlobals();
|
ReleaseObjAllocGlobals();
|
||||||
|
|
||||||
|
|
@ -61,3 +61,10 @@ uint32_t ObjectAllocUsage(uint32_t heapId) {
|
||||||
|
|
||||||
return result;
|
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);
|
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);
|
uint32_t ObjectAllocUsage(uint32_t heapId);
|
||||||
|
|
||||||
|
void ObjectAllocDestroy();
|
||||||
|
|
||||||
#endif
|
#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;
|
void* indexStack = static_cast<char*>(this->m_obj) + heapObjects * objSize;
|
||||||
this->m_indexStack = reinterpret_cast<uint32_t*>(indexStack);
|
this->m_indexStack = reinterpret_cast<uint32_t*>(indexStack);
|
||||||
this->m_bytes = heapObjects * objSize;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < heapObjects; i++) {
|
for (int32_t i = 0; i < heapObjects; i++) {
|
||||||
this->m_indexStack[i] = i;
|
this->m_indexStack[i] = i;
|
||||||
|
|
@ -90,11 +89,6 @@ void* CObjectHeap::Ptr(uint32_t index, uint32_t objSize, uint32_t heapObjects) {
|
||||||
bytes[3]);
|
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;
|
return static_cast<char*>(this->m_obj) + objSize * index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ class CObjectHeap {
|
||||||
void* m_obj = nullptr;
|
void* m_obj = nullptr;
|
||||||
uint32_t* m_indexStack = nullptr;
|
uint32_t* m_indexStack = nullptr;
|
||||||
uint32_t m_allocated = 0;
|
uint32_t m_allocated = 0;
|
||||||
uint32_t m_bytes = 0;
|
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
CObjectHeap() = default;
|
CObjectHeap() = default;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,71 @@ int32_t CObjectHeapList::New(uint32_t* index, void** obj, bool zero) {
|
||||||
return 1;
|
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 CObjectHeapList::BlocksAllocated() {
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
for (uint32_t i = 0; i < this->m_heaps.Count(); ++i) {
|
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_objSize = 0;
|
||||||
uint32_t m_objsPerBlock = 128;
|
uint32_t m_objsPerBlock = 128;
|
||||||
uint32_t m_numFullHeaps = 0;
|
uint32_t m_numFullHeaps = 0;
|
||||||
uint32_t uint1C = 0;
|
uint32_t m_hasEmptyHeaps = 0;
|
||||||
uint32_t uint20 = 0;
|
uint32_t uint20 = 0;
|
||||||
uint32_t m_fullestHeap = 0;
|
uint32_t m_fullestHeap = 0;
|
||||||
char m_heapName[80];
|
char m_heapName[80];
|
||||||
uint32_t uint78 = 0;
|
uint32_t uint78 = 0;
|
||||||
uint32_t uint7C = 0;
|
uint32_t uint7C = 0;
|
||||||
uint32_t uint80 = 0;
|
uint32_t uint80 = 0;
|
||||||
uint8_t char84 = 1;
|
uint8_t m_freeEmptyHeaps = 1;
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
int32_t New(uint32_t* index, void** obj, bool zero);
|
int32_t New(uint32_t* index, void** obj, bool zero);
|
||||||
|
void Delete(uint32_t index);
|
||||||
|
void FreeEmptyHeaps();
|
||||||
uint32_t BlocksAllocated();
|
uint32_t BlocksAllocated();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue