#include "memory_pages.h" MemoryPage::MemoryPage(uint16_t chunk_size, uint64_t typecode) { pcb.byte_count_per_chunk = chunk_size; pcb.total_buffer_size = sizeof(data_buffer); pcb.typecode_of_chunk = typecode; } uint16_t MemoryPage::chunkSize() const { return pcb.byte_count_per_chunk - MemoryChunk::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_chunks_count += inc; return data_ptr->pcb.active_chunks_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); } ChunkControlBlock* MemoryPage::getChunkPtr(int index) { auto member_cnt = maxCapacity(); auto chunk_size = chunkRawSize(); ChunkControlBlock* chunk_ptr = nullptr; if (index >= 0 && index < member_cnt) { chunk_ptr = (ChunkControlBlock*)(data_buffer + index * chunk_size); } else if (index < 0 && index >= -member_cnt) { chunk_ptr = (ChunkControlBlock*)(data_buffer + (member_cnt + index) * chunk_size); } lock(); if (chunk_ptr) { chunk_ptr->page_refer = this; chunk_ptr->chunk_index = index; } release(); return chunk_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::chunkTypeCode() const { auto data_ptr = const_cast(this); std::lock_guard g(data_ptr->pcb.access_protected); return pcb.typecode_of_chunk; } 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_chunk; } uint16_t MemoryPage::maxCapacity() const { uint16_t cnt = sizeof(data_buffer); return cnt / this->chunkRawSize(); } // chunk ================================================================= const uint32_t MemoryChunk::data_buffer_offset = MemoryChunk::validOffset(); uint32_t MemoryChunk::validOffset() { uint32_t remains = sizeof(ChunkControlBlock) % 16; uint32_t times = sizeof(ChunkControlBlock) / 16; return (remains ? times + 1 : times) * 16; } uint32_t MemoryChunk::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; } MemoryChunk::MemoryChunk(ChunkControlBlock* access_bind) : data_ptr((ChunkControlBlock*)access_bind) {} uint16_t MemoryChunk::typeSize() const { auto page_ptr = data_ptr->page_refer; return page_ptr->chunkRawSize(); } void MemoryChunk::accessUpdate(uint64_t time_usec) { data_ptr->page_refer->accessRecord(time_usec); } bool MemoryChunk::isActived(ChunkControlBlock* refer) { refer->page_refer->lock(); auto mark = refer->refer_count; refer->page_refer->release(); return mark; } void MemoryChunk::referAdd() { data_ptr->page_refer->lock(); data_ptr->refer_count++; data_ptr->page_refer->release(); } void MemoryChunk::referSub() { data_ptr->page_refer->lock(); data_ptr->refer_count--; data_ptr->page_refer->release(); } unsigned char* MemoryChunk::dataLock() { data_ptr->page_refer->lock(); return ((unsigned char*)data_ptr) + data_buffer_offset; } void MemoryChunk::release() { data_ptr->page_refer->release(); }