157 lines
4.0 KiB
C++
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();
|
|
}
|