#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(this); std::lock_guard 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 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); } 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(this); std::lock_guard g(data_ptr->pcb.access_protected); return pcb.typecode_of_element; } uint16_t MemoryPage::chunkRawSize() 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::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(); }