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
|
.DS_Store
|
||||||
.idea
|
.vs
|
||||||
.vscode
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
||||||
/build
|
/build
|
||||||
/cmake-build-*
|
/cmake-build-*
|
||||||
|
/out
|
||||||
|
|
||||||
|
/CMakeSettings.json
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,13 @@ CDataAllocator::CDataAllocator(uint32_t bytesPerData, uint32_t dataPerBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CDataAllocator::~CDataAllocator() {
|
CDataAllocator::~CDataAllocator() {
|
||||||
|
if (this->m_blockList) {
|
||||||
|
Clear(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
||||||
|
#if defined(WHOA_BUILD_ASSERTIONS)
|
||||||
if (this->m_dataUsed) {
|
if (this->m_dataUsed) {
|
||||||
if (!fileName) {
|
if (!fileName) {
|
||||||
fileName == __FILE__;
|
fileName == __FILE__;
|
||||||
|
|
@ -21,7 +25,7 @@ void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SErrDisplayErrorFmt(
|
SErrDisplayErrorFmt(
|
||||||
0x8510007E,
|
STORM_ERROR(0x7E),
|
||||||
fileName,
|
fileName,
|
||||||
lineNumber,
|
lineNumber,
|
||||||
1,
|
1,
|
||||||
|
|
@ -34,6 +38,7 @@ void CDataAllocator::Clear(const char* fileName, int32_t lineNumber) {
|
||||||
this->m_dataPerBlock,
|
this->m_dataPerBlock,
|
||||||
this->m_bytesPerData);
|
this->m_bytesPerData);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (this->m_blockList) {
|
while (this->m_blockList) {
|
||||||
auto block = this->m_blockList;
|
auto block = this->m_blockList;
|
||||||
|
|
@ -63,7 +68,7 @@ CDataAllocator::Data* CDataAllocator::GetData(int32_t zero, const char* fileName
|
||||||
lineNumber,
|
lineNumber,
|
||||||
0));
|
0));
|
||||||
Block* block = reinterpret_cast<Block*>(memory);
|
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;
|
this->m_dataList = data;
|
||||||
for (uint32_t i = 0; i < this->m_dataPerBlock - 1; ++i) {
|
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->m_next = reinterpret_cast<Data*>(next);
|
||||||
data = data->m_next;
|
data = data->m_next;
|
||||||
}
|
}
|
||||||
data->m_next = 0;
|
data->m_next = nullptr;
|
||||||
block->m_next = this->m_blockList;
|
block->m_next = this->m_blockList;
|
||||||
this->m_blockList = block;
|
this->m_blockList = block;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,25 @@
|
||||||
#define COMMON_MEMORY_C_DATA_ALLOCATOR_HPP
|
#define COMMON_MEMORY_C_DATA_ALLOCATOR_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
#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 {
|
class CDataAllocator {
|
||||||
public:
|
public:
|
||||||
|
|
@ -21,6 +40,11 @@ class CDataAllocator {
|
||||||
Data* GetData(int32_t zero, const char* fileName, int32_t lineNumber);
|
Data* GetData(int32_t zero, const char* fileName, int32_t lineNumber);
|
||||||
void PutData(void* data, 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
|
// Member variables
|
||||||
uint32_t m_bytesPerData = sizeof(Data);
|
uint32_t m_bytesPerData = sizeof(Data);
|
||||||
uint32_t m_dataPerBlock = 1;
|
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