| 58 | }; |
| 59 | |
| 60 | TEST_F(AllocationPoolTest, hugePages) { |
| 61 | constexpr int64_t kHugePageSize = memory::AllocationTraits::kHugePageSize; |
| 62 | auto allocationPool = std::make_unique<memory::AllocationPool>(pool_.get()); |
| 63 | allocationPool->setHugePageThreshold(128 << 10); |
| 64 | int32_t counter = 0; |
| 65 | for (;;) { |
| 66 | allocationPool->newRun(32 << 10); |
| 67 | // Initial allocations round up to 64K |
| 68 | EXPECT_EQ(1, allocationPool->numRanges()); |
| 69 | EXPECT_EQ(allocationPool->testingFreeAddressableBytes(), 64 << 10); |
| 70 | allocationPool->newRun(64 << 10); |
| 71 | EXPECT_LE(128 << 10, pool_->currentBytes()); |
| 72 | allocationPool->allocateFixed(64 << 10); |
| 73 | // Now at end of second 64K range, next will go to huge pages. |
| 74 | setByte(allocationPool->allocateFixed(11)); |
| 75 | EXPECT_LE((2 << 20) - 11, allocationPool->testingFreeAddressableBytes()); |
| 76 | // The first 2MB of the hugepage run are marked reserved. |
| 77 | EXPECT_LE((2048 + 128) << 10, pool_->currentBytes()); |
| 78 | |
| 79 | // The next allocation starts reserves the next 2MB of the mmapped range. |
| 80 | setByte(allocationPool->allocateFixed(2 << 20)); |
| 81 | EXPECT_LE((4096 + 128) << 10, pool_->currentBytes()); |
| 82 | |
| 83 | // Allocate the rest. |
| 84 | allocationPool->allocateFixed( |
| 85 | allocationPool->testingFreeAddressableBytes()); |
| 86 | |
| 87 | // We expect 3 ranges, 2 small and one large. |
| 88 | EXPECT_EQ(3, allocationPool->numRanges()); |
| 89 | |
| 90 | // We allocate more, expect a larger mmap. |
| 91 | allocationPool->allocateFixed(1); |
| 92 | |
| 93 | // The first is at least 15 huge pages. The next is at least 31. The mmaps |
| 94 | // may have unused addresses at either end, so count one huge page less than |
| 95 | // the nominal size. |
| 96 | EXPECT_LE((62 << 20) - 1, allocationPool->testingFreeAddressableBytes()); |
| 97 | |
| 98 | // We make a 5GB extra large allocation. |
| 99 | allocationPool->allocateFixed(5UL << 30); |
| 100 | EXPECT_EQ(5, allocationPool->numRanges()); |
| 101 | |
| 102 | // 5G is an even multiple of huge page, no free space at end. But it can be |
| 103 | // the mmap happens to start at 2MB boundary so we get another 2MB. |
| 104 | EXPECT_GE(kHugePageSize, allocationPool->testingFreeAddressableBytes()); |
| 105 | |
| 106 | EXPECT_LE( |
| 107 | (5UL << 30) + (31 << 20) + (128 << 10), |
| 108 | allocationPool->allocatedBytes()); |
| 109 | EXPECT_LE((5UL << 30) + (31 << 20) + (128 << 10), pool_->currentBytes()); |
| 110 | |
| 111 | if (counter++ >= 1) { |
| 112 | break; |
| 113 | } |
| 114 | |
| 115 | // Repeat the above after a clear(). |
| 116 | allocationPool->clear(); |
| 117 | // Should be empty after clear(). |
nothing calls this directly
no test coverage detected