summaryrefslogtreecommitdiff
path: root/lib/scudo/standalone/tests/primary_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/scudo/standalone/tests/primary_test.cpp')
-rw-r--r--lib/scudo/standalone/tests/primary_test.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/scudo/standalone/tests/primary_test.cpp b/lib/scudo/standalone/tests/primary_test.cpp
index 329a4c119..a6cfc6bdb 100644
--- a/lib/scudo/standalone/tests/primary_test.cpp
+++ b/lib/scudo/standalone/tests/primary_test.cpp
@@ -188,3 +188,32 @@ TEST(ScudoPrimaryTest, PrimaryThreaded) {
testPrimaryThreaded<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
testPrimaryThreaded<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
}
+
+// Through a simple allocation that spans two pages, verify that releaseToOS
+// actually releases some bytes (at least one page worth). This is a regression
+// test for an error in how the release criteria were computed.
+template <typename Primary> static void testReleaseToOS() {
+ auto Deleter = [](Primary *P) {
+ P->unmapTestOnly();
+ delete P;
+ };
+ std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter);
+ Allocator->init(/*ReleaseToOsInterval=*/-1);
+ typename Primary::CacheT Cache;
+ Cache.init(nullptr, Allocator.get());
+ const scudo::uptr Size = scudo::getPageSizeCached() * 2;
+ EXPECT_TRUE(Primary::canAllocate(Size));
+ const scudo::uptr ClassId =
+ Primary::SizeClassMap::getClassIdBySize(Size);
+ void *P = Cache.allocate(ClassId);
+ EXPECT_NE(P, nullptr);
+ Cache.deallocate(ClassId, P);
+ Cache.destroy(nullptr);
+ EXPECT_GT(Allocator->releaseToOS(), 0U);
+}
+
+TEST(ScudoPrimaryTest, ReleaseToOS) {
+ using SizeClassMap = scudo::DefaultSizeClassMap;
+ testReleaseToOS<scudo::SizeClassAllocator32<SizeClassMap, 18U>>();
+ testReleaseToOS<scudo::SizeClassAllocator64<SizeClassMap, 24U>>();
+}