Refactor interface between backend and frontend (#530)

* Rename to use Config, rather than StateHandle/Globals/Backend
* Make Backend a type on Config that contains the address space management implementation
* Make Ranges part of the Backend configuration, so we can reuse code for different ways of managing memory
* Pull the common chains of range definitions into separate files for reuse.
* Move PagemapEntry to CommonConfig
* Expose Pagemap through backend, so frontend doesn't see Pagemap directly
* Remove global Pal and use DefaultPal, where one is not pass explicitly.

Co-authored-by: David Chisnall <davidchisnall@users.noreply.github.com>
Co-authored-by: Nathaniel Filardo <105816689+nwf-msr@users.noreply.github.com>
This commit is contained in:
Matthew Parkinson
2022-05-31 10:45:04 +01:00
committed by GitHub
parent 1b8aa6bc0d
commit 03c9da6aa4
42 changed files with 765 additions and 538 deletions

View File

@@ -11,20 +11,38 @@ int main()
// # define SNMALLOC_TRACING
# include <snmalloc/backend/backend.h>
# include <snmalloc/backend/standard_range.h>
# include <snmalloc/backend_helpers/backend_helpers.h>
# include <snmalloc/snmalloc_core.h>
// Specify type of allocator
# define SNMALLOC_PROVIDE_OWN_CONFIG
namespace snmalloc
{
class CustomGlobals : public BackendAllocator<Pal, false>
class CustomConfig : public CommonConfig
{
public:
using GlobalPoolState = PoolState<CoreAllocator<CustomGlobals>>;
using Pal = DefaultPal;
using PagemapEntry = DefaultPagemapEntry;
private:
using Backend = BackendAllocator<Pal, false>;
using ConcretePagemap =
FlatPagemap<MIN_CHUNK_BITS, PagemapEntry, Pal, false>;
public:
using Pagemap = BasicPagemap<Pal, ConcretePagemap, PagemapEntry, false>;
public:
using LocalState = StandardLocalState<
Pal,
Pagemap,
Pipe<PalRange<Pal>, PagemapRegisterRange<Pagemap, false>>>;
using GlobalPoolState = PoolState<CoreAllocator<CustomConfig>>;
using Backend = BackendAllocator<Pal, PagemapEntry, Pagemap, LocalState>;
private:
SNMALLOC_REQUIRE_CONSTINIT
inline static GlobalPoolState alloc_pool;
@@ -65,7 +83,7 @@ namespace snmalloc
static CapPtr<
T,
typename B::template with_wildness<capptr::dimension::Wildness::Tame>>
capptr_domesticate(typename Backend::LocalState*, CapPtr<T, B> p)
capptr_domesticate(LocalState*, CapPtr<T, B> p)
{
domesticate_count++;
@@ -85,7 +103,7 @@ namespace snmalloc
{
std::cout << "Patching over corruption" << std::endl;
*domesticate_patch_location = domesticate_patch_value;
snmalloc::CustomGlobals::domesticate_patch_location = nullptr;
snmalloc::CustomConfig::domesticate_patch_location = nullptr;
}
return CapPtr<
@@ -95,7 +113,7 @@ namespace snmalloc
}
};
using Alloc = LocalAllocator<CustomGlobals>;
using Alloc = LocalAllocator<CustomConfig>;
}
# define SNMALLOC_NAME_MANGLE(a) test_##a
@@ -103,11 +121,11 @@ namespace snmalloc
int main()
{
snmalloc::CustomGlobals::init(); // init pagemap
snmalloc::CustomGlobals::domesticate_count = 0;
snmalloc::CustomConfig::Pagemap::concretePagemap.init(); // init pagemap
snmalloc::CustomConfig::domesticate_count = 0;
LocalEntropy entropy;
entropy.init<Pal>();
entropy.init<DefaultPal>();
key_global = FreeListKey(entropy.get_free_list_key());
auto alloc1 = new Alloc();
@@ -123,21 +141,20 @@ int main()
alloc2->flush();
// Clobber the linkage but not the back pointer
snmalloc::CustomGlobals::domesticate_patch_location =
snmalloc::CustomConfig::domesticate_patch_location =
static_cast<uintptr_t*>(p);
snmalloc::CustomGlobals::domesticate_patch_value =
*static_cast<uintptr_t*>(p);
snmalloc::CustomConfig::domesticate_patch_value = *static_cast<uintptr_t*>(p);
memset(p, 0xA5, sizeof(void*));
snmalloc::CustomGlobals::domesticate_trace = true;
snmalloc::CustomGlobals::domesticate_count = 0;
snmalloc::CustomConfig::domesticate_trace = true;
snmalloc::CustomConfig::domesticate_count = 0;
// Open a new slab, so that slow path will pick up the message queue. That
// means this should be a sizeclass we've not used before, even internally.
auto q = alloc1->alloc(512);
std::cout << "Allocated q " << q << std::endl;
snmalloc::CustomGlobals::domesticate_trace = false;
snmalloc::CustomConfig::domesticate_trace = false;
/*
* Expected domestication calls in the above message passing:
@@ -152,8 +169,8 @@ int main()
* after q).
*/
static constexpr size_t expected_count =
snmalloc::CustomGlobals::Options.QueueHeadsAreTame ? 2 : 3;
SNMALLOC_CHECK(snmalloc::CustomGlobals::domesticate_count == expected_count);
snmalloc::CustomConfig::Options.QueueHeadsAreTame ? 2 : 3;
SNMALLOC_CHECK(snmalloc::CustomConfig::domesticate_count == expected_count);
// Prevent the allocators from going out of scope during the above test
alloc1->flush();

View File

@@ -11,7 +11,7 @@
using namespace snmalloc;
using CustomGlobals = FixedGlobals<PALNoAlloc<DefaultPal>>;
using CustomGlobals = FixedRangeConfig<PALNoAlloc<DefaultPal>>;
using FixedAlloc = LocalAllocator<CustomGlobals>;
int main()
@@ -23,8 +23,8 @@ int main()
// It is also large enough for the example to run in.
// For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example.
auto size = bits::one_at_bit(28);
auto oe_base = Pal::reserve(size);
Pal::notify_using<NoZero>(oe_base, size);
auto oe_base = DefaultPal::reserve(size);
DefaultPal::notify_using<NoZero>(oe_base, size);
auto oe_end = pointer_offset(oe_base, size);
std::cout << "Allocated region " << oe_base << " - "
<< pointer_offset(oe_base, size) << std::endl;

View File

@@ -367,6 +367,6 @@ int main(int argc, char** argv)
our_malloc_usable_size(nullptr) == 0,
"malloc_usable_size(nullptr) should be zero");
snmalloc::debug_check_empty<snmalloc::Globals>();
snmalloc::debug_check_empty<snmalloc::StandardConfig>();
return 0;
}

View File

@@ -184,7 +184,7 @@ void test_calloc()
alloc.dealloc(p, size);
}
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
}
void test_double_alloc()
@@ -229,7 +229,7 @@ void test_double_alloc()
}
}
}
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
}
void test_external_pointer()
@@ -273,7 +273,7 @@ void test_external_pointer()
alloc.dealloc(p1, size);
}
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
};
void check_offset(void* base, void* interior)
@@ -305,7 +305,7 @@ void test_external_pointer_large()
auto& alloc = ThreadAlloc::get();
constexpr size_t count_log = Pal::address_bits > 32 ? 5 : 3;
constexpr size_t count_log = DefaultPal::address_bits > 32 ? 5 : 3;
constexpr size_t count = 1 << count_log;
// Pre allocate all the objects
size_t* objects[count];

View File

@@ -65,8 +65,8 @@ void test_pagemap(bool bounded)
if (bounded)
{
auto size = bits::one_at_bit(30);
auto base = Pal::reserve(size);
Pal::notify_using<NoZero>(base, size);
auto base = DefaultPal::reserve(size);
DefaultPal::notify_using<NoZero>(base, size);
std::cout << "Fixed base: " << base << " (" << size << ") "
<< " end: " << pointer_offset(base, size) << std::endl;
auto [heap_base, heap_size] = pagemap_test_bound.init(base, size);

View File

@@ -12,7 +12,7 @@ struct PoolAEntry : Pooled<PoolAEntry>
PoolAEntry() : field(1){};
};
using PoolA = Pool<PoolAEntry, Alloc::StateHandle>;
using PoolA = Pool<PoolAEntry, Alloc::Config>;
struct PoolBEntry : Pooled<PoolBEntry>
{
@@ -22,14 +22,14 @@ struct PoolBEntry : Pooled<PoolBEntry>
PoolBEntry(int f) : field(f){};
};
using PoolB = Pool<PoolBEntry, Alloc::StateHandle>;
using PoolB = Pool<PoolBEntry, Alloc::Config>;
void test_alloc()
{
auto ptr = PoolA::acquire();
SNMALLOC_CHECK(ptr != nullptr);
// Pool allocations should not be visible to debug_check_empty.
snmalloc::debug_check_empty<Alloc::StateHandle>();
snmalloc::debug_check_empty<Alloc::Config>();
PoolA::release(ptr);
}

View File

@@ -8,7 +8,7 @@ int main()
auto r = a.alloc(16);
snmalloc::debug_check_empty<snmalloc::Globals>(&result);
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
if (result != false)
{
abort();
@@ -16,7 +16,7 @@ int main()
a.dealloc(r);
snmalloc::debug_check_empty<snmalloc::Globals>(&result);
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
if (result != true)
{
abort();
@@ -24,7 +24,7 @@ int main()
r = a.alloc(16);
snmalloc::debug_check_empty<snmalloc::Globals>(&result);
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
if (result != false)
{
abort();
@@ -32,7 +32,7 @@ int main()
a.dealloc(r);
snmalloc::debug_check_empty<snmalloc::Globals>(&result);
snmalloc::debug_check_empty<snmalloc::StandardConfig>(&result);
if (result != true)
{
abort();

View File

@@ -12,7 +12,7 @@
namespace snmalloc
{
using Alloc = snmalloc::LocalAllocator<snmalloc::Globals>;
using Alloc = snmalloc::LocalAllocator<snmalloc::StandardConfig>;
}
using namespace snmalloc;

View File

@@ -12,7 +12,7 @@
#define SNMALLOC_PROVIDE_OWN_CONFIG
namespace snmalloc
{
using CustomGlobals = FixedGlobals<PALNoAlloc<DefaultPal>>;
using CustomGlobals = FixedRangeConfig<PALNoAlloc<DefaultPal>>;
using Alloc = LocalAllocator<CustomGlobals>;
}

View File

@@ -19,7 +19,7 @@ namespace snmalloc
{ \
current_test = __PRETTY_FUNCTION__; \
MessageBuilder<1024> mb{"Starting test: " msg "\n", ##__VA_ARGS__}; \
Pal::message(mb.get_message()); \
DefaultPal::message(mb.get_message()); \
} while (0)
/**
@@ -33,7 +33,7 @@ namespace snmalloc
do \
{ \
MessageBuilder<1024> mb{msg "\n", ##__VA_ARGS__}; \
Pal::message(mb.get_message()); \
DefaultPal::message(mb.get_message()); \
} while (0)
}

View File

@@ -154,7 +154,7 @@ void test_tasks(size_t num_tasks, size_t count, size_t size)
}
#ifndef NDEBUG
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
#endif
};

View File

@@ -19,7 +19,7 @@ namespace test
{
size_t rand = (size_t)r.next();
size_t offset = bits::clz(rand);
if constexpr (Pal::address_bits > 32)
if constexpr (DefaultPal::address_bits > 32)
{
if (offset > 30)
offset = 30;
@@ -47,7 +47,7 @@ namespace test
alloc.dealloc(objects[i]);
}
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
}
void test_external_pointer(xoroshiro::p128r64& r)

View File

@@ -60,7 +60,7 @@ void test_alloc_dealloc(size_t count, size_t size, bool write)
}
}
snmalloc::debug_check_empty<Globals>();
snmalloc::debug_check_empty<StandardConfig>();
}
int main(int, char**)

View File

@@ -64,7 +64,7 @@ void print_stack_trace()
void _cdecl error(int signal)
{
snmalloc::UNUSED(signal);
snmalloc::Pal::message("*****ABORT******");
snmalloc::DefaultPal::message("*****ABORT******");
print_stack_trace();
@@ -75,7 +75,7 @@ LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
snmalloc::UNUSED(ExceptionInfo);
snmalloc::Pal::message("*****UNHANDLED EXCEPTION******");
snmalloc::DefaultPal::message("*****UNHANDLED EXCEPTION******");
print_stack_trace();