mirror of
https://github.com/thunderbrewhq/common.git
synced 2025-12-12 03:02:29 +00:00
feat(objectalloc): add ObjectAlloc and ObjectAllocAddHeap
This commit is contained in:
parent
2c03a4a5df
commit
d1bfb1394e
10 changed files with 238 additions and 0 deletions
|
|
@ -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
51
common/ObjectAlloc.cpp
Normal 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
10
common/ObjectAlloc.hpp
Normal 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
|
||||||
41
common/objectalloc/CObjectHeap.cpp
Normal file
41
common/objectalloc/CObjectHeap.cpp
Normal 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;
|
||||||
|
}
|
||||||
18
common/objectalloc/CObjectHeap.hpp
Normal file
18
common/objectalloc/CObjectHeap.hpp
Normal 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
|
||||||
38
common/objectalloc/CObjectHeapList.cpp
Normal file
38
common/objectalloc/CObjectHeapList.cpp
Normal 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;
|
||||||
|
}
|
||||||
27
common/objectalloc/CObjectHeapList.hpp
Normal file
27
common/objectalloc/CObjectHeapList.hpp
Normal 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
|
||||||
14
common/objectalloc/ObjAllocGlobals.cpp
Normal file
14
common/objectalloc/ObjAllocGlobals.cpp
Normal 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();
|
||||||
|
}
|
||||||
21
common/objectalloc/ObjAllocGlobals.hpp
Normal file
21
common/objectalloc/ObjAllocGlobals.hpp
Normal 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
17
test/ObjectAlloc.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue