#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; } void MemoryPage::accessRecord(uint64_t timepoint_usec) { std::lock_guard g(pcb.access_protected); pcb.curr_access_usec = timepoint_usec; pcb.acc_count_per_cycle++; } uint32_t MemoryPage::timesClear() { std::lock_guard g(pcb.access_protected); auto value = pcb.acc_count_per_cycle; pcb.acc_count_per_cycle = 0; return value; } std::pair MemoryPage::getRecords() const { auto data_ptr = const_cast(this); std::lock_guard g(data_ptr->pcb.access_protected); return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle); } char* MemoryPage::getElementPtr(int index) { auto member_cnt = elementCount(); auto element_size = elementSize(); char* element_ptr = nullptr; if (index >= 0 && index < member_cnt) { element_ptr = data_buffer + index * element_size; } else if (index < 0 && index >= -member_cnt) { element_ptr = data_buffer + (member_cnt + index) * element_size; } lock(); if (element_ptr) { auto data_ptr = (ElementControlBlock*)element_ptr; data_ptr->page_refer = this; data_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(this); std::lock_guard g(data_ptr->pcb.access_protected); return pcb.typecode_of_element; } uint16_t MemoryPage::elementSize() const { auto data_ptr = const_cast(this); std::lock_guard g(data_ptr->pcb.access_protected); return pcb.byte_count_per_element; } uint16_t MemoryPage::elementCount() const { uint16_t cnt = sizeof(data_buffer); return cnt / this->elementSize(); } uint32_t MemoryElement::validOffset() { uint32_t remains = sizeof(ElementControlBlock) % 8; uint32_t times = sizeof(ElementControlBlock) / 8; return (remains ? times + 1 : times) * 8; } 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(char* access_bind) : data_ptr((ElementControlBlock*)access_bind) { buffer_offset = validOffset(); } void MemoryElement::accessRecUpdate(uint64_t time_usec) { data_ptr->page_refer->accessRecord(time_usec); } uint8_t MemoryElement::isActived() const { data_ptr->page_refer->lock(); auto mark = data_ptr->active_mark; data_ptr->page_refer->release(); return mark; } void MemoryElement::setActive(uint8_t ste) { data_ptr->page_refer->lock(); data_ptr->active_mark = ste; data_ptr->page_refer->release(); } char* MemoryElement::dataLock() { data_ptr->page_refer->lock(); return ((char*)data_ptr) + buffer_offset; } void MemoryElement::release() { data_ptr->page_refer->release(); }