mirror of
https://github.com/thunderbrewhq/common.git
synced 2025-12-12 03:02:29 +00:00
feat(memory): add assertion mode check to CDataAllocator
This commit is contained in:
parent
739adccafd
commit
d4ee19c6af
4 changed files with 76 additions and 4 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,6 +1,10 @@
|
|||
.DS_Store
|
||||
.idea
|
||||
.vs
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
/build
|
||||
/cmake-build-*
|
||||
/out
|
||||
|
||||
/CMakeSettings.json
|
||||
|
|
|
|||
|
|
@ -11,9 +11,13 @@ CDataAllocator::CDataAllocator(uint32_t bytesPerData, uint32_t dataPerBlock) {
|
|||
}
|
||||
|
||||
CDataAllocator::~CDataAllocator() {
|
||||
if (this->m_blockList) {
|
||||
Clear(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
||||
#if defined(WHOA_BUILD_ASSERTIONS)
|
||||
if (this->m_dataUsed) {
|
||||
if (!fileName) {
|
||||
fileName == __FILE__;
|
||||
|
|
@ -21,7 +25,7 @@ void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
|||
}
|
||||
|
||||
SErrDisplayErrorFmt(
|
||||
0x8510007E,
|
||||
STORM_ERROR(0x7E),
|
||||
fileName,
|
||||
lineNumber,
|
||||
1,
|
||||
|
|
@ -34,6 +38,7 @@ void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
|||
this->m_dataPerBlock,
|
||||
this->m_bytesPerData);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (this->m_blockList) {
|
||||
auto block = this->m_blockList;
|
||||
|
|
@ -63,7 +68,7 @@ CDataAllocator::Data* CDataAllocator::GetData(int32_t zero, const char* fileName
|
|||
lineNumber,
|
||||
0));
|
||||
Block* block = reinterpret_cast<Block*>(memory);
|
||||
Data* data = reinterpret_cast<Data*>(memory + sizeof(Block*));
|
||||
Data* data = reinterpret_cast<Data*>(memory + sizeof(Block));
|
||||
|
||||
this->m_dataList = data;
|
||||
for (uint32_t i = 0; i < this->m_dataPerBlock - 1; ++i) {
|
||||
|
|
@ -71,7 +76,7 @@ CDataAllocator::Data* CDataAllocator::GetData(int32_t zero, const char* fileName
|
|||
data->m_next = reinterpret_cast<Data*>(next);
|
||||
data = data->m_next;
|
||||
}
|
||||
data->m_next = 0;
|
||||
data->m_next = nullptr;
|
||||
block->m_next = this->m_blockList;
|
||||
this->m_blockList = block;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,25 @@
|
|||
#define COMMON_MEMORY_C_DATA_ALLOCATOR_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
|
||||
#define ALLOCATOR_GET(allocator) allocator.GetData(0, __FILE__, __LINE__)
|
||||
#define ALLOCATOR_GET_ZERO(allocator) allocator.GetData(1, __FILE__, __LINE__)
|
||||
#define ALLOCATOR_NEW(allocator, T, ...) (new (allocator.GetData(0, __FILE__, __LINE__)) T(__VA_ARGS__))
|
||||
#define ALLOCATOR_NEW_ZERO(allocator, T, ...) (new (allocator.GetData(1, __FILE__, __LINE__)) T(__VA_ARGS__))
|
||||
|
||||
#define ALLOCATOR_PUT(allocator, ptr) allocator.PutData(ptr, __FILE__, __LINE__)
|
||||
#define ALLOCATOR_PUT(allocator, ptr) \
|
||||
do { \
|
||||
if (ptr) { \
|
||||
using __data_object = std::remove_pointer<std::decay<decltype(ptr)>::type>::type; \
|
||||
(ptr)->~__data_object(); \
|
||||
allocator.PutData(ptr, __FILE__, __LINE__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
class CDataAllocator {
|
||||
public:
|
||||
|
|
@ -21,6 +40,11 @@ class CDataAllocator {
|
|||
Data* GetData(int32_t zero, const char* fileName, int32_t lineNumber);
|
||||
void PutData(void* data, const char* fileName, int32_t lineNumber);
|
||||
|
||||
inline uint32_t BytesPerData() const { return this->m_bytesPerData; }
|
||||
inline uint32_t DataPerBlock() const { return this->m_dataPerBlock; }
|
||||
inline uint32_t DataUsed() const { return this->m_dataUsed; }
|
||||
|
||||
private:
|
||||
// Member variables
|
||||
uint32_t m_bytesPerData = sizeof(Data);
|
||||
uint32_t m_dataPerBlock = 1;
|
||||
|
|
|
|||
39
test/DataAllocator.cpp
Normal file
39
test/DataAllocator.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include "common/DataAllocator.hpp"
|
||||
#include "test/Test.hpp"
|
||||
|
||||
struct TestContainer
|
||||
{
|
||||
uint32_t value[10];
|
||||
};
|
||||
|
||||
TEST_CASE("CDataAllocator::CDataAllocator", "[dataallocator]") {
|
||||
SECTION("constructs new data allocator") {
|
||||
CDataAllocator allocator(sizeof(TestContainer), 2);
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CDataAllocator::GetData", "[dataallocator]") {
|
||||
SECTION("get allocated objects") {
|
||||
CDataAllocator allocator(sizeof(TestContainer), 2);
|
||||
auto container = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
auto container2 = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
auto container3 = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
REQUIRE(container);
|
||||
REQUIRE(container2);
|
||||
REQUIRE(container3);
|
||||
REQUIRE(allocator.DataUsed() == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("CDataAllocator::PutData", "[dataallocator]") {
|
||||
SECTION("return allocated objects") {
|
||||
CDataAllocator allocator(sizeof(TestContainer), 2);
|
||||
auto container = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
auto container2 = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
auto container3 = (TestContainer*)allocator.GetData(0, __FILE__, __LINE__);
|
||||
allocator.PutData(container, __FILE__, __LINE__);
|
||||
allocator.PutData(container3, __FILE__, __LINE__);
|
||||
REQUIRE(allocator.DataUsed() == 1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue