aligned_page_pool_ut.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "aligned_page_pool.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/system/info.h>
  4. namespace NKikimr {
  5. namespace NMiniKQL {
  6. Y_UNIT_TEST_SUITE(TAlignedPagePoolTest) {
  7. Y_UNIT_TEST(AlignedMmapPageSize) {
  8. TAlignedPagePool::ResetGlobalsUT();
  9. TAlignedPagePoolImpl<TFakeAlignedMmap> alloc(__LOCATION__);
  10. int munmaps = 0;
  11. TFakeAlignedMmap::OnMunmap = [&](void* addr, size_t s) {
  12. Y_UNUSED(addr);
  13. Y_UNUSED(s);
  14. munmaps ++;
  15. };
  16. auto size = TAlignedPagePool::POOL_PAGE_SIZE;
  17. auto block = std::shared_ptr<void>(alloc.GetBlock(size), [&](void* addr) { alloc.ReturnBlock(addr, size); });
  18. TFakeAlignedMmap::OnMunmap = {};
  19. UNIT_ASSERT_EQUAL(0, munmaps);
  20. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(block.get()), TAlignedPagePool::POOL_PAGE_SIZE);
  21. UNIT_ASSERT_VALUES_EQUAL(alloc.GetFreePageCount()
  22. , TAlignedPagePool::ALLOC_AHEAD_PAGES);
  23. UNIT_ASSERT_VALUES_EQUAL(alloc.GetAllocated()
  24. , TAlignedPagePool::POOL_PAGE_SIZE + TAlignedPagePool::ALLOC_AHEAD_PAGES*TAlignedPagePool::POOL_PAGE_SIZE
  25. );
  26. }
  27. Y_UNIT_TEST(UnalignedMmapPageSize) {
  28. TAlignedPagePool::ResetGlobalsUT();
  29. TAlignedPagePoolImpl<TFakeUnalignedMmap> alloc(__LOCATION__);
  30. int munmaps = 0;
  31. TFakeUnalignedMmap::OnMunmap = [&](void* addr, size_t s) {
  32. Y_UNUSED(addr);
  33. if (munmaps == 0) {
  34. UNIT_ASSERT_VALUES_EQUAL(s, TAlignedPagePool::POOL_PAGE_SIZE - 1);
  35. } else {
  36. UNIT_ASSERT_VALUES_EQUAL(s, 1);
  37. }
  38. munmaps ++;
  39. };
  40. auto size = TAlignedPagePool::POOL_PAGE_SIZE;
  41. auto block = std::shared_ptr<void>(alloc.GetBlock(size), [&](void* addr) { alloc.ReturnBlock(addr, size); });
  42. TFakeUnalignedMmap::OnMunmap = {};
  43. UNIT_ASSERT_EQUAL(2, munmaps);
  44. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(block.get()), 2 * TAlignedPagePool::POOL_PAGE_SIZE);
  45. UNIT_ASSERT_VALUES_EQUAL(alloc.GetFreePageCount()
  46. , TAlignedPagePool::ALLOC_AHEAD_PAGES - 1);
  47. UNIT_ASSERT_VALUES_EQUAL(alloc.GetAllocated()
  48. , TAlignedPagePool::POOL_PAGE_SIZE + (TAlignedPagePool::ALLOC_AHEAD_PAGES - 1) * TAlignedPagePool::POOL_PAGE_SIZE
  49. );
  50. }
  51. Y_UNIT_TEST(AlignedMmapUnalignedSize) {
  52. TAlignedPagePool::ResetGlobalsUT();
  53. TAlignedPagePoolImpl<TFakeAlignedMmap> alloc(__LOCATION__);
  54. auto smallSize = NSystemInfo::GetPageSize();
  55. auto size = smallSize + 1024 * TAlignedPagePool::POOL_PAGE_SIZE;
  56. int munmaps = 0;
  57. TFakeAlignedMmap::OnMunmap = [&](void* addr, size_t s) {
  58. if (munmaps == 0) {
  59. UNIT_ASSERT_VALUES_EQUAL(s, TAlignedPagePool::POOL_PAGE_SIZE - smallSize);
  60. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(addr), TAlignedPagePool::POOL_PAGE_SIZE + size);
  61. } else {
  62. UNIT_ASSERT_VALUES_EQUAL(s, smallSize);
  63. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(addr), TAlignedPagePool::POOL_PAGE_SIZE + TAlignedPagePool::ALLOC_AHEAD_PAGES * TAlignedPagePool::POOL_PAGE_SIZE + size - smallSize);
  64. }
  65. munmaps ++;
  66. };
  67. auto block = std::shared_ptr<void>(alloc.GetBlock(size), [&](void* addr) { alloc.ReturnBlock(addr, size); });
  68. TFakeAlignedMmap::OnMunmap = {};
  69. UNIT_ASSERT_EQUAL(2, munmaps);
  70. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(block.get()), TAlignedPagePool::POOL_PAGE_SIZE);
  71. UNIT_ASSERT_VALUES_EQUAL(alloc.GetFreePageCount()
  72. , TAlignedPagePool::ALLOC_AHEAD_PAGES - 1);
  73. UNIT_ASSERT_VALUES_EQUAL(alloc.GetAllocated()
  74. , size + (TAlignedPagePool::ALLOC_AHEAD_PAGES - 1) * TAlignedPagePool::POOL_PAGE_SIZE
  75. );
  76. }
  77. Y_UNIT_TEST(UnalignedMmapUnalignedSize) {
  78. TAlignedPagePool::ResetGlobalsUT();
  79. TAlignedPagePoolImpl<TFakeUnalignedMmap> alloc(__LOCATION__);
  80. auto smallSize = NSystemInfo::GetPageSize();
  81. auto size = smallSize + 1024 * TAlignedPagePool::POOL_PAGE_SIZE;
  82. int munmaps = 0;
  83. TFakeUnalignedMmap::OnMunmap = [&](void* addr, size_t s) {
  84. Y_UNUSED(addr);
  85. if (munmaps == 0) {
  86. UNIT_ASSERT_VALUES_EQUAL(s, TAlignedPagePool::POOL_PAGE_SIZE - 1);
  87. } else if (munmaps == 1) {
  88. UNIT_ASSERT_VALUES_EQUAL(s, TAlignedPagePool::POOL_PAGE_SIZE - smallSize);
  89. } else {
  90. UNIT_ASSERT_VALUES_EQUAL(s, smallSize + 1);
  91. }
  92. munmaps ++;
  93. };
  94. auto block = std::shared_ptr<void>(alloc.GetBlock(size), [&](void* addr) { alloc.ReturnBlock(addr, size); });
  95. TFakeUnalignedMmap::OnMunmap = {};
  96. UNIT_ASSERT_EQUAL(3, munmaps);
  97. UNIT_ASSERT_VALUES_EQUAL(reinterpret_cast<uintptr_t>(block.get()), 2 * TAlignedPagePool::POOL_PAGE_SIZE);
  98. UNIT_ASSERT_VALUES_EQUAL(alloc.GetFreePageCount()
  99. , TAlignedPagePool::ALLOC_AHEAD_PAGES - 2);
  100. UNIT_ASSERT_VALUES_EQUAL(alloc.GetAllocated()
  101. , size + (TAlignedPagePool::ALLOC_AHEAD_PAGES - 2) * TAlignedPagePool::POOL_PAGE_SIZE
  102. );
  103. }
  104. Y_UNIT_TEST(YellowZoneSwitchesCorrectlyBlock) {
  105. TAlignedPagePool::ResetGlobalsUT();
  106. TAlignedPagePoolImpl alloc(__LOCATION__);
  107. // choose relatively big chunk so ALLOC_AHEAD_PAGES don't affect the correctness of the test
  108. auto size = 1024 * TAlignedPagePool::POOL_PAGE_SIZE;
  109. alloc.SetLimit(size * 10);
  110. // 50% allocated -> no yellow zone
  111. auto block1 = alloc.GetBlock(size * 5);
  112. UNIT_ASSERT_VALUES_EQUAL(false, alloc.IsMemoryYellowZoneEnabled());
  113. // 70% allocated -> no yellow zone
  114. auto block2 = alloc.GetBlock(size * 2);
  115. UNIT_ASSERT_VALUES_EQUAL(false, alloc.IsMemoryYellowZoneEnabled());
  116. // 90% allocated -> yellow zone is enabled (> 80%)
  117. auto block3 = alloc.GetBlock(size * 2);
  118. UNIT_ASSERT_VALUES_EQUAL(true, alloc.IsMemoryYellowZoneEnabled());
  119. // 70% allocated -> yellow zone is still enabled (> 50%)
  120. alloc.ReturnBlock(block3, size * 2);
  121. UNIT_ASSERT_VALUES_EQUAL(true, alloc.IsMemoryYellowZoneEnabled());
  122. // 50% allocated -> yellow zone is disabled
  123. alloc.ReturnBlock(block2, size * 2);
  124. UNIT_ASSERT_VALUES_EQUAL(false, alloc.IsMemoryYellowZoneEnabled());
  125. // 0% allocated -> yellow zone is disabled
  126. alloc.ReturnBlock(block1, size * 5);
  127. UNIT_ASSERT_VALUES_EQUAL(false, alloc.IsMemoryYellowZoneEnabled());
  128. }
  129. Y_UNIT_TEST(YellowZoneZeroDivision) {
  130. TAlignedPagePool::ResetGlobalsUT();
  131. TAlignedPagePoolImpl alloc(__LOCATION__);
  132. alloc.SetLimit(0);
  133. UNIT_ASSERT_EQUAL(false, alloc.IsMemoryYellowZoneEnabled());
  134. }
  135. } // Y_UNIT_TEST_SUITE(TAlignedPagePoolTest)
  136. } // namespace NMiniKQL
  137. } // namespace NKikimr