[NFC][scudo] Inline some functions into ScudoPrimaryTest

This commit is contained in:
Vitaly Buka 2021-04-02 00:58:09 -07:00
parent f343a73059
commit bb1e5399e4
1 changed files with 71 additions and 102 deletions

View File

@ -21,37 +21,6 @@
// 32-bit architectures. It's not something we want to encourage, but we still
// should ensure the tests pass.
template <typename Primary> static void testPrimary() {
const scudo::uptr NumberOfAllocations = 32U;
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());
for (scudo::uptr I = 0; I <= 16U; I++) {
const scudo::uptr Size = 1UL << I;
if (!Primary::canAllocate(Size))
continue;
const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size);
void *Pointers[NumberOfAllocations];
for (scudo::uptr J = 0; J < NumberOfAllocations; J++) {
void *P = Cache.allocate(ClassId);
memset(P, 'B', Size);
Pointers[J] = P;
}
for (scudo::uptr J = 0; J < NumberOfAllocations; J++)
Cache.deallocate(ClassId, Pointers[J]);
}
Cache.destroy(nullptr);
Allocator->releaseToOS();
scudo::ScopedString Str(1024);
Allocator->getStats(&Str);
Str.output();
}
struct TestConfig1 {
static const scudo::uptr PrimaryRegionSizeLog = 18U;
static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
@ -84,13 +53,16 @@ struct Config : public BaseConfig {
using SizeClassMap = SizeClassMapT;
};
template <typename BaseConfig, typename SizeClassMapT> struct MakeAllocator {
using Value = scudo::SizeClassAllocator64<Config<BaseConfig, SizeClassMapT>>;
};
template <typename BaseConfig, typename SizeClassMapT>
struct SizeClassAllocator
: public scudo::SizeClassAllocator64<Config<BaseConfig, SizeClassMapT>> {};
template <typename SizeClassMapT>
struct MakeAllocator<TestConfig1, SizeClassMapT> {
using Value = scudo::SizeClassAllocator32<Config<TestConfig1, SizeClassMapT>>;
struct SizeClassAllocator<TestConfig1, SizeClassMapT>
: public scudo::SizeClassAllocator32<Config<TestConfig1, SizeClassMapT>> {};
template <typename BaseConfig, typename SizeClassMapT>
struct TestAllocator : public SizeClassAllocator<BaseConfig, SizeClassMapT> {
~TestAllocator() { this->unmapTestOnly(); }
};
namespace testing {
@ -114,8 +86,31 @@ using ScudoPrimaryTestTypes = testing::Types<
TYPED_TEST_CASE(ScudoPrimaryTest, ScudoPrimaryTestTypes);
TYPED_TEST(ScudoPrimaryTest, BasicPrimary) {
using SizeClassMap = scudo::DefaultSizeClassMap;
testPrimary<typename MakeAllocator<TypeParam, SizeClassMap>::Value>();
using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>;
std::unique_ptr<Primary> Allocator(new Primary);
Allocator->init(/*ReleaseToOsInterval=*/-1);
typename Primary::CacheT Cache;
Cache.init(nullptr, Allocator.get());
const scudo::uptr NumberOfAllocations = 32U;
for (scudo::uptr I = 0; I <= 16U; I++) {
const scudo::uptr Size = 1UL << I;
if (!Primary::canAllocate(Size))
continue;
const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size);
void *Pointers[NumberOfAllocations];
for (scudo::uptr J = 0; J < NumberOfAllocations; J++) {
void *P = Cache.allocate(ClassId);
memset(P, 'B', Size);
Pointers[J] = P;
}
for (scudo::uptr J = 0; J < NumberOfAllocations; J++)
Cache.deallocate(ClassId, Pointers[J]);
}
Cache.destroy(nullptr);
Allocator->releaseToOS();
scudo::ScopedString Str(1024);
Allocator->getStats(&Str);
Str.output();
}
struct SmallRegionsConfig {
@ -166,12 +161,9 @@ TEST(ScudoPrimaryTest, Primary64OOM) {
Allocator.unmapTestOnly();
}
template <typename Primary> static void testIteratePrimary() {
auto Deleter = [](Primary *P) {
P->unmapTestOnly();
delete P;
};
std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter);
TYPED_TEST(ScudoPrimaryTest, PrimaryIterate) {
using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>;
std::unique_ptr<Primary> Allocator(new Primary);
Allocator->init(/*ReleaseToOsInterval=*/-1);
typename Primary::CacheT Cache;
Cache.init(nullptr, Allocator.get());
@ -205,50 +197,40 @@ template <typename Primary> static void testIteratePrimary() {
Str.output();
}
TYPED_TEST(ScudoPrimaryTest, PrimaryIterate) {
using SizeClassMap = scudo::DefaultSizeClassMap;
testIteratePrimary<typename MakeAllocator<TypeParam, SizeClassMap>::Value>();
}
static std::mutex Mutex;
static std::condition_variable Cv;
static bool Ready;
template <typename Primary> static void performAllocations(Primary *Allocator) {
static thread_local typename Primary::CacheT Cache;
Cache.init(nullptr, Allocator);
std::vector<std::pair<scudo::uptr, void *>> V;
{
std::unique_lock<std::mutex> Lock(Mutex);
while (!Ready)
Cv.wait(Lock);
}
for (scudo::uptr I = 0; I < 256U; I++) {
const scudo::uptr Size = std::rand() % Primary::SizeClassMap::MaxSize / 4;
const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size);
void *P = Cache.allocate(ClassId);
if (P)
V.push_back(std::make_pair(ClassId, P));
}
while (!V.empty()) {
auto Pair = V.back();
Cache.deallocate(Pair.first, Pair.second);
V.pop_back();
}
Cache.destroy(nullptr);
}
template <typename Primary> static void testPrimaryThreaded() {
Ready = false;
auto Deleter = [](Primary *P) {
P->unmapTestOnly();
delete P;
};
std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter);
TYPED_TEST(ScudoPrimaryTest, PrimaryThreaded) {
using Primary = TestAllocator<TypeParam, scudo::SvelteSizeClassMap>;
std::unique_ptr<Primary> Allocator(new Primary);
Allocator->init(/*ReleaseToOsInterval=*/-1);
std::mutex Mutex;
std::condition_variable Cv;
bool Ready = false;
std::thread Threads[32];
for (scudo::uptr I = 0; I < ARRAY_SIZE(Threads); I++)
Threads[I] = std::thread(performAllocations<Primary>, Allocator.get());
Threads[I] = std::thread([&]() {
static thread_local typename Primary::CacheT Cache;
Cache.init(nullptr, Allocator.get());
std::vector<std::pair<scudo::uptr, void *>> V;
{
std::unique_lock<std::mutex> Lock(Mutex);
while (!Ready)
Cv.wait(Lock);
}
for (scudo::uptr I = 0; I < 256U; I++) {
const scudo::uptr Size =
std::rand() % Primary::SizeClassMap::MaxSize / 4;
const scudo::uptr ClassId =
Primary::SizeClassMap::getClassIdBySize(Size);
void *P = Cache.allocate(ClassId);
if (P)
V.push_back(std::make_pair(ClassId, P));
}
while (!V.empty()) {
auto Pair = V.back();
Cache.deallocate(Pair.first, Pair.second);
V.pop_back();
}
Cache.destroy(nullptr);
});
{
std::unique_lock<std::mutex> Lock(Mutex);
Ready = true;
@ -262,20 +244,12 @@ template <typename Primary> static void testPrimaryThreaded() {
Str.output();
}
TYPED_TEST(ScudoPrimaryTest, PrimaryThreaded) {
using SizeClassMap = scudo::SvelteSizeClassMap;
testPrimaryThreaded<typename MakeAllocator<TypeParam, SizeClassMap>::Value>();
}
// 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);
TYPED_TEST(ScudoPrimaryTest, ReleaseToOS) {
using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>;
std::unique_ptr<Primary> Allocator(new Primary);
Allocator->init(/*ReleaseToOsInterval=*/-1);
typename Primary::CacheT Cache;
Cache.init(nullptr, Allocator.get());
@ -288,8 +262,3 @@ template <typename Primary> static void testReleaseToOS() {
Cache.destroy(nullptr);
EXPECT_GT(Allocator->releaseToOS(), 0U);
}
TYPED_TEST(ScudoPrimaryTest, ReleaseToOS) {
using SizeClassMap = scudo::DefaultSizeClassMap;
testReleaseToOS<typename MakeAllocator<TypeParam, SizeClassMap>::Value>();
}