feat(objectalloc): add ObjectAlloc and ObjectAllocAddHeap

This commit is contained in:
fallenoak 2022-12-28 09:41:40 -06:00
parent 2c03a4a5df
commit d1bfb1394e
No known key found for this signature in database
GPG key ID: 7628F8E61AEA070D
10 changed files with 238 additions and 0 deletions

View file

@ -1,5 +1,6 @@
file(GLOB COMMON_SOURCES file(GLOB COMMON_SOURCES
"*.cpp" "*.cpp"
"objectalloc/*.cpp"
"ref/*.cpp" "ref/*.cpp"
"string/*.cpp" "string/*.cpp"
) )

51
common/ObjectAlloc.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "common/ObjectAlloc.hpp"
#include "common/objectalloc/ObjAllocGlobals.hpp"
#include <storm/Error.hpp>
#include <storm/String.hpp>
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;
}

10
common/ObjectAlloc.hpp Normal file
View file

@ -0,0 +1,10 @@
#ifndef COMMON_OBJECT_ALLOC_HPP
#define COMMON_OBJECT_ALLOC_HPP
#include <cstdint>
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

View file

@ -0,0 +1,41 @@
#include "common/objectalloc/CObjectHeap.hpp"
#include <cstring>
#include <storm/Memory.hpp>
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<char*>(this->m_obj) + heapObjects * objSize;
this->m_indexStack = reinterpret_cast<uint32_t*>(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<char*>(this->m_obj) + objSize * *index;
if (zero) {
memset(objPtr, 0, objSize);
}
if (a6) {
*a6 = objPtr;
}
return 1;
}

View file

@ -0,0 +1,18 @@
#ifndef COMMON_OBJECTALLOC_C_OBJECT_HEAP_HPP
#define COMMON_OBJECTALLOC_C_OBJECT_HEAP_HPP
#include <cstdint>
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

View file

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

View file

@ -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 <storm/Array.hpp>
class CObjectHeapList {
public:
// Member variables
TSGrowableArray<CObjectHeap> 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

View file

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

View file

@ -0,0 +1,21 @@
#ifndef COMMON_OBJECTALLOC_OBJ_ALLOC_GLOBALS_HPP
#define COMMON_OBJECTALLOC_OBJ_ALLOC_GLOBALS_HPP
#include "common/objectalloc/CObjectHeapList.hpp"
#include <storm/Thread.hpp>
class OBJALLOCGLOBALS {
public:
// Static variables
static OBJALLOCGLOBALS s_globals;
static SCritSect s_globalsLock;
// Member variables
TSGrowableArray<CObjectHeapList> objects;
};
OBJALLOCGLOBALS* GetObjAllocGlobals();
void ReleaseObjAllocGlobals();
#endif

17
test/ObjectAlloc.cpp Normal file
View file

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