forked from OSchip/llvm-project
[NFC][scudo] Inline some functions into ScudoPrimaryTest
This commit is contained in:
parent
f343a73059
commit
bb1e5399e4
|
@ -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>();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue