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:
committed by
GitHub
parent
1b8aa6bc0d
commit
03c9da6aa4
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
using Alloc = snmalloc::LocalAllocator<snmalloc::Globals>;
|
||||
using Alloc = snmalloc::LocalAllocator<snmalloc::StandardConfig>;
|
||||
}
|
||||
|
||||
using namespace snmalloc;
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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**)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user