123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #include "size_map.h"
- #include "shm_helper.h"
- #include "shm_manager.h"
- #include "shm_config.h"
- namespace bg
- {
- namespace detail
- {
- bool SizeMap::Init()
- {
- // ·ÖÒ³
- size_t size = 8;
- size_t class_cnt = 0;
- size_t index_total = 1;
- size_t index = 0;
- do
- {
- size_t alig_size = bg::detail::SizeMap::CalcAlignment(size);
- if(size)
- {
- class_cnt = CLASS_TOTAL_BYTES / size;
- if(class_cnt)
- {
- class_cnt = std::min<size_t>(MAX_CLASSS, class_cnt);
- class_cnt >>= 2;
- }
- }
- size_t alig_page_byte = 0LL;
- do
- {
- for(alig_page_byte += PAGE_BYTES; alig_page_byte % size > alig_page_byte >> 3; alig_page_byte += PAGE_BYTES);
- } while(alig_page_byte / size < class_cnt);
- size_t page_cnt = BYTES_TO_PAGES(alig_page_byte);
- if(index_total > 1 && page_cnt == m_class_to_pages[index_total - 1]
- && alig_page_byte / size == alig_page_byte / m_class_to_size[index_total - 1])
- {
- m_class_to_size[index_total - 1] = size;
- }
- else
- {
- m_class_to_pages[index_total] = page_cnt;
- m_class_to_size[index_total] = size;
- index_total++;
- }
- size += alig_size;
- } while(size <= CLASS_MAX_BYTES);
- if(index_total > CLASS_MAX_COUNT)
- {
- SHM_WARN("too many size classes, found: %u, max: %u", index_total, CLASS_MAX_COUNT);
- }
- else
- {
- if(index_total > 1u)
- {
- size = 0;
- for(char i = 1; i < index_total; ++i)
- {
- for(size_t j = m_class_to_size[i]; j >= size; size += SMALL_CALIGNMENT)
- {
- if(size <= BYTES_COMP_VALUE)
- {
- m_index_to_class[SMALL_BYTES_TO_INDEX(size)] = i;
- }
- else
- {
- m_index_to_class[BIG_BYTES_TO_INDEX(size)] = i;
- }
- }
- }
- }
- size = 0;
- while(true)
- {
- if(size <= BYTES_COMP_VALUE)
- {
- index = m_index_to_class[SMALL_BYTES_TO_INDEX(size)];
- }
- else
- {
- index = m_index_to_class[BIG_BYTES_TO_INDEX(size)];
- }
- if(index >= index_total)
- {
- goto FAIL;
- }
- size_t value = this->m_class_to_size[index];
- if(index > 1)
- {
- if(m_class_to_size[index - 1] >= size)
- {
- SHM_WARN("size class too large, class: %zu, size: %zu", index, size);
- return false;
- }
- }
- if(!value)
- {
- SHM_WARN("bad class: %zu, size: %zu", index, size);
- return false;
- }
- if(size > BYTES_COMP_VALUE)
- {
- size += SMALL_BYTES_TO_INDEX(BYTES_COMP_VALUE);
- if(size <= CLASS_MAX_BYTES)
- {
- continue;
- }
- return true;
- }
- size += SMALL_CALIGNMENT;
- }
- }
- FAIL:
- SHM_WARN("bad size class, class: %u, size: %lu", index, size);
- return false;
- }
- size_t SizeMap::CalcAlignment(size_t bytes)
- {
- size_t result; // rax
- char bit{};
- result = PAGE_BYTES;
- if(bytes < (PAGE_BYTES << 4))
- {
- if(bytes <= 0x7F)
- {
- return (-(int64_t)(bytes < 0x10) & 0xFFFFFFFFFFFFFFF8LL) + 16;
- }
- else
- {
- for(int i = 16; i >= 1; i >>= 1)
- {
- size_t temp = bytes >> i;
- if(temp)
- {
- bit += i;
- bytes = temp;
- }
- }
- result = (1ul << bit) >> 3;
- return result;
- }
- }
- return result;
- }
- }
- }
|