1 //===-- Unittests for a freestore -------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 #include "src/__support/freestore.h"
12 #include "test/UnitTest/Test.h"
14 using LIBC_NAMESPACE::Block
;
15 using LIBC_NAMESPACE::FreeList
;
16 using LIBC_NAMESPACE::FreeStore
;
17 using LIBC_NAMESPACE::FreeTrie
;
18 using LIBC_NAMESPACE::cpp::byte
;
19 using LIBC_NAMESPACE::cpp::optional
;
21 // Inserting or removing blocks too small to be tracked does nothing.
22 TEST(LlvmLibcFreeStore
, TooSmall
) {
24 optional
<Block
<> *> maybeBlock
= Block
<>::init(mem
);
25 ASSERT_TRUE(maybeBlock
.has_value());
26 Block
<> *too_small
= *maybeBlock
;
27 maybeBlock
= too_small
->split(sizeof(Block
<>::offset_type
));
28 ASSERT_TRUE(maybeBlock
.has_value());
29 Block
<> *remainder
= *maybeBlock
;
32 store
.set_range({0, 4096});
33 store
.insert(too_small
);
34 store
.insert(remainder
);
36 EXPECT_EQ(store
.remove_best_fit(too_small
->inner_size()), remainder
);
37 store
.remove(too_small
);
40 TEST(LlvmLibcFreeStore
, RemoveBestFit
) {
42 optional
<Block
<> *> maybeBlock
= Block
<>::init(mem
);
43 ASSERT_TRUE(maybeBlock
.has_value());
45 Block
<> *smallest
= *maybeBlock
;
46 maybeBlock
= smallest
->split(sizeof(FreeList
) + sizeof(Block
<>::offset_type
));
47 ASSERT_TRUE(maybeBlock
.has_value());
48 Block
<> *largest_small
= *maybeBlock
;
50 largest_small
->split(sizeof(FreeTrie::Node
) +
51 sizeof(Block
<>::offset_type
) - alignof(max_align_t
));
52 ASSERT_TRUE(maybeBlock
.has_value());
53 ASSERT_GT(largest_small
->inner_size(), smallest
->inner_size());
55 Block
<> *remainder
= *maybeBlock
;
58 store
.set_range({0, 4096});
59 store
.insert(smallest
);
60 store
.insert(largest_small
);
61 store
.insert(remainder
);
63 // Find exact match for smallest.
64 ASSERT_EQ(store
.remove_best_fit(smallest
->inner_size()), smallest
);
65 store
.insert(smallest
);
67 // Find exact match for largest.
68 ASSERT_EQ(store
.remove_best_fit(largest_small
->inner_size()), largest_small
);
69 store
.insert(largest_small
);
71 // Search smallest for best fit.
72 ASSERT_EQ(store
.remove_best_fit(smallest
->inner_size() + 1), largest_small
);
73 store
.insert(largest_small
);
75 // Continue search for best fit to large blocks.
76 EXPECT_EQ(store
.remove_best_fit(largest_small
->inner_size() + 1), remainder
);
79 TEST(LlvmLibcFreeStore
, Remove
) {
81 optional
<Block
<> *> maybeBlock
= Block
<>::init(mem
);
82 ASSERT_TRUE(maybeBlock
.has_value());
84 Block
<> *small
= *maybeBlock
;
85 maybeBlock
= small
->split(sizeof(FreeList
) + sizeof(Block
<>::offset_type
));
86 ASSERT_TRUE(maybeBlock
.has_value());
88 Block
<> *remainder
= *maybeBlock
;
91 store
.set_range({0, 4096});
93 store
.insert(remainder
);
95 store
.remove(remainder
);
96 ASSERT_EQ(store
.remove_best_fit(remainder
->inner_size()),
97 static_cast<Block
<> *>(nullptr));
99 ASSERT_EQ(store
.remove_best_fit(small
->inner_size()),
100 static_cast<Block
<> *>(nullptr));