WsComponentPool/ECSMemoryPool/memory_pages.cpp

157 lines
4.0 KiB
C++

#include "memory_pages.h"
MemoryPage::MemoryPage(uint16_t element_size, uint64_t typecode)
{
pcb.byte_count_per_element = element_size;
pcb.total_buffer_size = sizeof(data_buffer);
pcb.typecode_of_element = typecode;
}
uint16_t MemoryPage::chunkSize() const
{
return pcb.byte_count_per_element - MemoryElement::data_buffer_offset;
}
uint16_t MemoryPage::getActiveCount(uint16_t inc) const
{
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
data_ptr->pcb.active_elements_count += inc;
return data_ptr->pcb.active_elements_count;
}
void MemoryPage::accessRecord(uint64_t timepoint_usec) {
std::lock_guard<std::mutex> g(pcb.access_protected);
pcb.curr_access_usec = timepoint_usec;
pcb.acc_count_per_cycle++;
}
uint32_t MemoryPage::timesClear() {
std::lock_guard<std::mutex> g(pcb.access_protected);
auto value = pcb.acc_count_per_cycle;
pcb.acc_count_per_cycle = 0;
return value;
}
std::pair<uint64_t, uint32_t> MemoryPage::getRecords() const {
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle);
}
ElementControlBlock* MemoryPage::getChunkPtr(int index) {
auto member_cnt = maxChunkCapacity();
auto element_size = chunkRawSize();
ElementControlBlock* element_ptr = nullptr;
if (index >= 0 && index < member_cnt) {
element_ptr = (ElementControlBlock*)(data_buffer + index * element_size);
}
else if (index < 0 && index >= -member_cnt) {
element_ptr = (ElementControlBlock*)(data_buffer + (member_cnt + index) * element_size);
}
lock();
if (element_ptr) {
element_ptr->page_refer = this;
element_ptr->element_index = index;
}
release();
return element_ptr;
}
void MemoryPage::lock()
{
pcb.access_protected.lock();
}
void MemoryPage::release() {
#pragma warning(push)
#pragma warning(disable : 26110)
pcb.access_protected.unlock();
#pragma warning(pop)
}
uint64_t MemoryPage::elementTypeCode() const
{
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return pcb.typecode_of_element;
}
uint16_t MemoryPage::chunkRawSize() const {
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return pcb.byte_count_per_element;
}
uint16_t MemoryPage::maxChunkCapacity() const {
uint16_t cnt = sizeof(data_buffer);
return cnt / this->chunkRawSize();
}
// element =================================================================
const uint32_t MemoryElement::data_buffer_offset = MemoryElement::validOffset();
uint32_t MemoryElement::validOffset()
{
uint32_t remains = sizeof(ElementControlBlock) % 16;
uint32_t times = sizeof(ElementControlBlock) / 16;
return (remains ? times + 1 : times) * 16;
}
uint32_t MemoryElement::rawSize(uint32_t data_type_size)
{
uint32_t minimal_size = validOffset() + data_type_size;
auto remains = minimal_size % 16;
auto times = minimal_size / 16;
return (remains ? times + 1 : times) * 16;
}
MemoryElement::MemoryElement(ElementControlBlock* access_bind)
: data_ptr((ElementControlBlock*)access_bind) {}
uint16_t MemoryElement::typeSize() const
{
auto page_ptr = data_ptr->page_refer;
return page_ptr->chunkRawSize();
}
void MemoryElement::accessUpdate(uint64_t time_usec)
{
data_ptr->page_refer->accessRecord(time_usec);
}
bool MemoryElement::isActived(ElementControlBlock* refer)
{
refer->page_refer->lock();
auto mark = refer->refer_count;
refer->page_refer->release();
return mark;
}
void MemoryElement::referAdd()
{
data_ptr->page_refer->lock();
data_ptr->refer_count++;
data_ptr->page_refer->release();
}
void MemoryElement::referSub()
{
data_ptr->page_refer->lock();
data_ptr->refer_count--;
data_ptr->page_refer->release();
}
unsigned char* MemoryElement::dataLock()
{
data_ptr->page_refer->lock();
return ((unsigned char*)data_ptr) + data_buffer_offset;
}
void MemoryElement::release()
{
data_ptr->page_refer->release();
}