size_map.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include "size_map.h"
  2. #include "shm_helper.h"
  3. #include "shm_manager.h"
  4. #include "shm_config.h"
  5. namespace bg
  6. {
  7. namespace detail
  8. {
  9. bool SizeMap::Init()
  10. {
  11. // ·ÖÒ³
  12. size_t size = 8;
  13. size_t class_cnt = 0;
  14. size_t index_total = 1;
  15. size_t index = 0;
  16. do
  17. {
  18. size_t alig_size = bg::detail::SizeMap::CalcAlignment(size);
  19. if(size)
  20. {
  21. class_cnt = CLASS_TOTAL_BYTES / size;
  22. if(class_cnt)
  23. {
  24. class_cnt = std::min<size_t>(MAX_CLASSS, class_cnt);
  25. class_cnt >>= 2;
  26. }
  27. }
  28. size_t alig_page_byte = 0LL;
  29. do
  30. {
  31. for(alig_page_byte += PAGE_BYTES; alig_page_byte % size > alig_page_byte >> 3; alig_page_byte += PAGE_BYTES);
  32. } while(alig_page_byte / size < class_cnt);
  33. size_t page_cnt = BYTES_TO_PAGES(alig_page_byte);
  34. if(index_total > 1 && page_cnt == m_class_to_pages[index_total - 1]
  35. && alig_page_byte / size == alig_page_byte / m_class_to_size[index_total - 1])
  36. {
  37. m_class_to_size[index_total - 1] = size;
  38. }
  39. else
  40. {
  41. m_class_to_pages[index_total] = page_cnt;
  42. m_class_to_size[index_total] = size;
  43. index_total++;
  44. }
  45. size += alig_size;
  46. } while(size <= CLASS_MAX_BYTES);
  47. if(index_total > CLASS_MAX_COUNT)
  48. {
  49. SHM_WARN("too many size classes, found: %u, max: %u", index_total, CLASS_MAX_COUNT);
  50. }
  51. else
  52. {
  53. if(index_total > 1u)
  54. {
  55. size = 0;
  56. for(char i = 1; i < index_total; ++i)
  57. {
  58. for(size_t j = m_class_to_size[i]; j >= size; size += SMALL_CALIGNMENT)
  59. {
  60. if(size <= BYTES_COMP_VALUE)
  61. {
  62. m_index_to_class[SMALL_BYTES_TO_INDEX(size)] = i;
  63. }
  64. else
  65. {
  66. m_index_to_class[BIG_BYTES_TO_INDEX(size)] = i;
  67. }
  68. }
  69. }
  70. }
  71. size = 0;
  72. while(true)
  73. {
  74. if(size <= BYTES_COMP_VALUE)
  75. {
  76. index = m_index_to_class[SMALL_BYTES_TO_INDEX(size)];
  77. }
  78. else
  79. {
  80. index = m_index_to_class[BIG_BYTES_TO_INDEX(size)];
  81. }
  82. if(index >= index_total)
  83. {
  84. goto FAIL;
  85. }
  86. size_t value = this->m_class_to_size[index];
  87. if(index > 1)
  88. {
  89. if(m_class_to_size[index - 1] >= size)
  90. {
  91. SHM_WARN("size class too large, class: %zu, size: %zu", index, size);
  92. return false;
  93. }
  94. }
  95. if(!value)
  96. {
  97. SHM_WARN("bad class: %zu, size: %zu", index, size);
  98. return false;
  99. }
  100. if(size > BYTES_COMP_VALUE)
  101. {
  102. size += SMALL_BYTES_TO_INDEX(BYTES_COMP_VALUE);
  103. if(size <= CLASS_MAX_BYTES)
  104. {
  105. continue;
  106. }
  107. return true;
  108. }
  109. size += SMALL_CALIGNMENT;
  110. }
  111. }
  112. FAIL:
  113. SHM_WARN("bad size class, class: %u, size: %lu", index, size);
  114. return false;
  115. }
  116. size_t SizeMap::CalcAlignment(size_t bytes)
  117. {
  118. size_t result; // rax
  119. char bit{};
  120. result = PAGE_BYTES;
  121. if(bytes < (PAGE_BYTES << 4))
  122. {
  123. if(bytes <= 0x7F)
  124. {
  125. return (-(int64_t)(bytes < 0x10) & 0xFFFFFFFFFFFFFFF8LL) + 16;
  126. }
  127. else
  128. {
  129. for(int i = 16; i >= 1; i >>= 1)
  130. {
  131. size_t temp = bytes >> i;
  132. if(temp)
  133. {
  134. bit += i;
  135. bytes = temp;
  136. }
  137. }
  138. result = (1ul << bit) >> 3;
  139. return result;
  140. }
  141. }
  142. return result;
  143. }
  144. }
  145. }