1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
2 | // Licensed under the MIT license. |
3 | |
4 | #include <cstdint> |
5 | #include <deque> |
6 | #include <thread> |
7 | #include "gtest/gtest.h" |
8 | |
9 | #include "core/light_epoch.h" |
10 | #include "core/malloc_fixed_page_size.h" |
11 | #include "device/null_disk.h" |
12 | |
13 | struct alignas(32) Item { |
14 | uint8_t buffer[32]; |
15 | }; |
16 | |
17 | using namespace FASTER::core; |
18 | |
19 | typedef MallocFixedPageSize<Item, FASTER::device::NullDisk> alloc_t; |
20 | |
21 | TEST(MallocFixedPageSize, AllocFree) { |
22 | LightEpoch epoch; |
23 | alloc_t allocator{}; |
24 | allocator.Initialize(256, epoch); |
25 | for(size_t idx = 0; idx < 1000000; ++idx) { |
26 | FixedPageAddress address = allocator.Allocate(); |
27 | Item* item = &allocator.Get(address); |
28 | ASSERT_EQ(0, reinterpret_cast<size_t>(item) % alignof(Item)); |
29 | allocator.FreeAtEpoch(address, 0); |
30 | } |
31 | ASSERT_EQ(1, allocator.free_list().size()); |
32 | } |
33 | |
34 | TEST(MallocFixedPageSize, Alloc) { |
35 | LightEpoch epoch; |
36 | alloc_t allocator{}; |
37 | allocator.Initialize(128, epoch); |
38 | for(size_t idx = 0; idx < 3200000; ++idx) { |
39 | FixedPageAddress address = allocator.Allocate(); |
40 | Item* item = &allocator.Get(address); |
41 | ASSERT_EQ(0, reinterpret_cast<size_t>(item) % alignof(Item)); |
42 | } |
43 | ASSERT_EQ(0, allocator.free_list().size()); |
44 | } |
45 | |
46 | |
47 | static void MultiThread_Worker(alloc_t* allocator) { |
48 | constexpr size_t kAllocCount = 1600000; |
49 | FixedPageAddress* addresses = new FixedPageAddress[kAllocCount]; |
50 | |
51 | for(size_t idx = 0; idx < kAllocCount; ++idx) { |
52 | addresses[idx] = allocator->Allocate(); |
53 | Item* item = &allocator->Get(addresses[idx]); |
54 | ASSERT_EQ(0, reinterpret_cast<size_t>(item) % alignof(Item)); |
55 | } |
56 | for(size_t idx = 0; idx < kAllocCount; ++idx) { |
57 | allocator->FreeAtEpoch(addresses[idx], idx); |
58 | } |
59 | ASSERT_EQ(kAllocCount, allocator->free_list().size()); |
60 | |
61 | delete[] addresses; |
62 | } |
63 | |
64 | TEST(MallocFixedPageSize, Concurrent) { |
65 | constexpr size_t kNumThreads = 2; |
66 | LightEpoch epoch; |
67 | alloc_t allocator{}; |
68 | allocator.Initialize(64, epoch); |
69 | std::deque<std::thread> threads{}; |
70 | for(size_t idx = 0; idx < kNumThreads; ++idx) { |
71 | threads.emplace_back(MultiThread_Worker, &allocator); |
72 | } |
73 | for(auto& thread : threads) { |
74 | thread.join(); |
75 | } |
76 | } |
77 | |
78 | int main(int argc, char** argv) { |
79 | ::testing::InitGoogleTest(&argc, argv); |
80 | return RUN_ALL_TESTS(); |
81 | } |