From d1bfb1394efb4efc97bdb626f4984968ad5984f5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Dec 2022 09:41:40 -0600 Subject: [PATCH] feat(objectalloc): add ObjectAlloc and ObjectAllocAddHeap --- common/CMakeLists.txt | 1 + common/ObjectAlloc.cpp | 51 ++++++++++++++++++++++++++ common/ObjectAlloc.hpp | 10 +++++ common/objectalloc/CObjectHeap.cpp | 41 +++++++++++++++++++++ common/objectalloc/CObjectHeap.hpp | 18 +++++++++ common/objectalloc/CObjectHeapList.cpp | 38 +++++++++++++++++++ common/objectalloc/CObjectHeapList.hpp | 27 ++++++++++++++ common/objectalloc/ObjAllocGlobals.cpp | 14 +++++++ common/objectalloc/ObjAllocGlobals.hpp | 21 +++++++++++ test/ObjectAlloc.cpp | 17 +++++++++ 10 files changed, 238 insertions(+) create mode 100644 common/ObjectAlloc.cpp create mode 100644 common/ObjectAlloc.hpp create mode 100644 common/objectalloc/CObjectHeap.cpp create mode 100644 common/objectalloc/CObjectHeap.hpp create mode 100644 common/objectalloc/CObjectHeapList.cpp create mode 100644 common/objectalloc/CObjectHeapList.hpp create mode 100644 common/objectalloc/ObjAllocGlobals.cpp create mode 100644 common/objectalloc/ObjAllocGlobals.hpp create mode 100644 test/ObjectAlloc.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index ce5f8c6..da3b683 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,5 +1,6 @@ file(GLOB COMMON_SOURCES "*.cpp" + "objectalloc/*.cpp" "ref/*.cpp" "string/*.cpp" ) diff --git a/common/ObjectAlloc.cpp b/common/ObjectAlloc.cpp new file mode 100644 index 0000000..a1cbed3 --- /dev/null +++ b/common/ObjectAlloc.cpp @@ -0,0 +1,51 @@ +#include "common/ObjectAlloc.hpp" +#include "common/objectalloc/ObjAllocGlobals.hpp" +#include +#include + +int32_t ObjectAlloc(uint32_t heapId, uint32_t* memHandle, void** objectPtr, bool a4) { + STORM_ASSERT(memHandle); + + *memHandle = 0; + + auto globals = GetObjAllocGlobals(); + + STORM_ASSERT(heapId < globals->objects.Count()); + + uint32_t index; + void* object; + + if (globals->objects[heapId].New(&index, &object, a4)) { + if (objectPtr) { + *objectPtr = object; + } + + ReleaseObjAllocGlobals(); + + *memHandle = index; + + return 1; + } + + ReleaseObjAllocGlobals(); + + return 0; +} + +uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool a4) { + STORM_ASSERT(objectSize > 0); + + auto globals = GetObjAllocGlobals(); + + uint32_t heapId = globals->objects.Count(); + auto heap = globals->objects.New(); + + heap->m_objSize = objectSize; + heap->m_objsPerBlock = objsPerBlock; + SStrCopy(heap->m_heapName, name, sizeof(heap->m_heapName)); + heap->char84 = a4; + + ReleaseObjAllocGlobals(); + + return heapId; +} diff --git a/common/ObjectAlloc.hpp b/common/ObjectAlloc.hpp new file mode 100644 index 0000000..e96eb86 --- /dev/null +++ b/common/ObjectAlloc.hpp @@ -0,0 +1,10 @@ +#ifndef COMMON_OBJECT_ALLOC_HPP +#define COMMON_OBJECT_ALLOC_HPP + +#include + +int32_t ObjectAlloc(uint32_t heapId, uint32_t* memHandle, void** objectPtr, bool a4); + +uint32_t ObjectAllocAddHeap(uint32_t objectSize, uint32_t objsPerBlock, const char* name, bool a4); + +#endif diff --git a/common/objectalloc/CObjectHeap.cpp b/common/objectalloc/CObjectHeap.cpp new file mode 100644 index 0000000..3b013f4 --- /dev/null +++ b/common/objectalloc/CObjectHeap.cpp @@ -0,0 +1,41 @@ +#include "common/objectalloc/CObjectHeap.hpp" +#include +#include + +int32_t CObjectHeap::Allocate(uint32_t objSize, uint32_t heapObjects, const char* heapName) { + this->m_obj = SMemAlloc(heapObjects * (objSize + sizeof(uint32_t)), heapName, 0, 0x0); + + void* indexStack = static_cast(this->m_obj) + heapObjects * objSize; + this->m_indexStack = reinterpret_cast(indexStack); + + for (int32_t i = 0; i < heapObjects; i++) { + this->m_indexStack[i] = i; + } + + this->m_allocated = 0; + + return this->m_obj != nullptr; +} + +int32_t CObjectHeap::New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** a6, bool zero) { + if (this->m_allocated >= heapObjects) { + return 0; + } + + if (!this->m_obj) { + this->Allocate(objSize, heapObjects, heapName); + } + + *index = this->m_indexStack[this->m_allocated++]; + void* objPtr = static_cast(this->m_obj) + objSize * *index; + + if (zero) { + memset(objPtr, 0, objSize); + } + + if (a6) { + *a6 = objPtr; + } + + return 1; +} diff --git a/common/objectalloc/CObjectHeap.hpp b/common/objectalloc/CObjectHeap.hpp new file mode 100644 index 0000000..be5b64b --- /dev/null +++ b/common/objectalloc/CObjectHeap.hpp @@ -0,0 +1,18 @@ +#ifndef COMMON_OBJECTALLOC_C_OBJECT_HEAP_HPP +#define COMMON_OBJECTALLOC_C_OBJECT_HEAP_HPP + +#include + +class CObjectHeap { + public: + // Member variables + void* m_obj; + uint32_t* m_indexStack; + uint32_t m_allocated; + + // Member functions + int32_t Allocate(uint32_t objSize, uint32_t heapObjects, const char* heapName); + int32_t New(uint32_t objSize, uint32_t heapObjects, uint32_t* index, const char* heapName, void** a6, bool zero); +}; + +#endif diff --git a/common/objectalloc/CObjectHeapList.cpp b/common/objectalloc/CObjectHeapList.cpp new file mode 100644 index 0000000..d65e049 --- /dev/null +++ b/common/objectalloc/CObjectHeapList.cpp @@ -0,0 +1,38 @@ +#include "common/objectalloc/CObjectHeapList.hpp" +#include "storm/Error.hpp" + +int32_t CObjectHeapList::New(uint32_t* index, void** a3, bool a4) { + CObjectHeap* heap = nullptr; + + if (this->uint24 < this->m_heaps.Count()) { + heap = &this->m_heaps[this->uint24]; + } + + if (!heap || heap->m_allocated == this->m_objsPerBlock || !heap->m_obj) { + if (this->m_heaps.Count() == this->m_numFullHeaps) { + this->uint24 = this->m_heaps.Count(); + + heap = this->m_heaps.New(); + + if (!heap->Allocate(this->m_objSize, this->m_objsPerBlock, this->m_heapName)) { + return 0; + } + } else { + // TODO + // Find available heap + STORM_ASSERT(false); + } + } + + if (!heap->New(this->m_objSize, this->m_objsPerBlock, index, this->m_heapName, a3, a4)) { + return 0; + } + + *index += this->uint24 * this->m_objsPerBlock; + + if (heap->m_allocated == this->m_objsPerBlock) { + this->m_numFullHeaps++; + } + + return 1; +} diff --git a/common/objectalloc/CObjectHeapList.hpp b/common/objectalloc/CObjectHeapList.hpp new file mode 100644 index 0000000..b2efb05 --- /dev/null +++ b/common/objectalloc/CObjectHeapList.hpp @@ -0,0 +1,27 @@ +#ifndef COMMON_OBJECTALLOC_C_OBJECT_HEAP_LIST_HPP +#define COMMON_OBJECTALLOC_C_OBJECT_HEAP_LIST_HPP + +#include "common/objectalloc/CObjectHeap.hpp" +#include + +class CObjectHeapList { + public: + // Member variables + TSGrowableArray m_heaps; + uint32_t m_objSize = 0; + uint32_t m_objsPerBlock = 128; + uint32_t m_numFullHeaps = 0; + uint32_t uint1C = 0; + uint32_t uint20 = 0; + uint32_t uint24 = 0; + char m_heapName[80]; + uint32_t uint78 = 0; + uint32_t uint7C = 0; + uint32_t uint80 = 0; + uint8_t char84 = 1; + + // Member functions + int32_t New(uint32_t* index, void** a3, bool a4); +}; + +#endif diff --git a/common/objectalloc/ObjAllocGlobals.cpp b/common/objectalloc/ObjAllocGlobals.cpp new file mode 100644 index 0000000..3dd8205 --- /dev/null +++ b/common/objectalloc/ObjAllocGlobals.cpp @@ -0,0 +1,14 @@ +#include "common/objectalloc/ObjAllocGlobals.hpp" + +OBJALLOCGLOBALS OBJALLOCGLOBALS::s_globals; +SCritSect OBJALLOCGLOBALS::s_globalsLock; + +OBJALLOCGLOBALS* GetObjAllocGlobals() { + OBJALLOCGLOBALS::s_globalsLock.Enter(); + + return &OBJALLOCGLOBALS::s_globals; +} + +void ReleaseObjAllocGlobals() { + OBJALLOCGLOBALS::s_globalsLock.Leave(); +} diff --git a/common/objectalloc/ObjAllocGlobals.hpp b/common/objectalloc/ObjAllocGlobals.hpp new file mode 100644 index 0000000..b06795d --- /dev/null +++ b/common/objectalloc/ObjAllocGlobals.hpp @@ -0,0 +1,21 @@ +#ifndef COMMON_OBJECTALLOC_OBJ_ALLOC_GLOBALS_HPP +#define COMMON_OBJECTALLOC_OBJ_ALLOC_GLOBALS_HPP + +#include "common/objectalloc/CObjectHeapList.hpp" +#include + +class OBJALLOCGLOBALS { + public: + // Static variables + static OBJALLOCGLOBALS s_globals; + static SCritSect s_globalsLock; + + // Member variables + TSGrowableArray objects; +}; + +OBJALLOCGLOBALS* GetObjAllocGlobals(); + +void ReleaseObjAllocGlobals(); + +#endif diff --git a/test/ObjectAlloc.cpp b/test/ObjectAlloc.cpp new file mode 100644 index 0000000..e9d5ea0 --- /dev/null +++ b/test/ObjectAlloc.cpp @@ -0,0 +1,17 @@ +#include "common/ObjectAlloc.hpp" +#include "test/Test.hpp" + +TEST_CASE("ObjectAllocAddHeap", "[objectalloc]") { + SECTION("creates a new heap and returns a heap id") { + struct Foo { + uint32_t field1; + uint32_t field2; + }; + + auto heapId1 = ObjectAllocAddHeap(sizeof(Foo), 1024, "Foo", true); + auto heapId2 = ObjectAllocAddHeap(sizeof(Foo), 1024, "Foo", true); + + CHECK(heapId1 == 0); + CHECK(heapId2 == 1); + } +}