Post large deallocations to original thread (#441)
* Post large deallocations to original thread This change sets all large allocations to be owned by the originating thread. This means they will be messaged back to the original thread before they can be reused. The following reason for making this change: * This will improve producer/consumer apps involving large allocations. * It enables the implementation of a more complex chunk allocator that reassembles chunks. * It addresses an issue with compartmentalisation where the handling of large allocations can result in meta-data ownership changing.
This commit is contained in:
committed by
GitHub
parent
3fb7c98364
commit
61314f2260
@@ -186,7 +186,7 @@ namespace snmalloc
|
||||
size_to_sizeclass_full(size),
|
||||
large_size_to_chunk_sizeclass(size),
|
||||
large_size_to_chunk_size(size),
|
||||
SharedStateHandle::fake_large_remote);
|
||||
core_alloc->public_state());
|
||||
// set up meta data so sizeclass is correct, and hence alloc size, and
|
||||
// external pointer.
|
||||
#ifdef SNMALLOC_TRACING
|
||||
@@ -194,9 +194,9 @@ namespace snmalloc
|
||||
<< bits::next_pow2_bits(size) << std::endl;
|
||||
#endif
|
||||
|
||||
// Note that meta data is not currently used for large allocs.
|
||||
// meta->initialise(size_to_sizeclass(size));
|
||||
UNUSED(meta);
|
||||
// Initialise meta data for a successful large allocation.
|
||||
if (meta != nullptr)
|
||||
meta->initialise_large();
|
||||
|
||||
if (zero_mem == YesZero)
|
||||
{
|
||||
@@ -662,56 +662,6 @@ namespace snmalloc
|
||||
return;
|
||||
}
|
||||
|
||||
// Large deallocation or null.
|
||||
// also checks for managed by page map.
|
||||
if (SNMALLOC_LIKELY(
|
||||
(p_tame != nullptr) && !entry.get_sizeclass().is_default()))
|
||||
{
|
||||
# if defined(__CHERI_PURE_CAPABILITY__) && defined(SNMALLOC_CHECK_CLIENT)
|
||||
dealloc_cheri_checks(p_tame.unsafe_ptr());
|
||||
# endif
|
||||
|
||||
size_t entry_sizeclass = entry.get_sizeclass().as_large();
|
||||
|
||||
size_t size = bits::one_at_bit(entry_sizeclass);
|
||||
size_t slab_sizeclass =
|
||||
metaentry_chunk_sizeclass_to_slab_sizeclass(entry_sizeclass);
|
||||
|
||||
// Check for start of allocation.
|
||||
snmalloc_check_client(
|
||||
pointer_align_down(p_tame, size) == p_tame,
|
||||
"Not start of an allocation.");
|
||||
|
||||
# ifdef SNMALLOC_TRACING
|
||||
std::cout << "Large deallocation: " << size
|
||||
<< " chunk sizeclass: " << slab_sizeclass << std::endl;
|
||||
# else
|
||||
UNUSED(size);
|
||||
# endif
|
||||
|
||||
auto slab_record =
|
||||
static_cast<ChunkRecord*>(entry.get_metaslab_no_remote());
|
||||
|
||||
SNMALLOC_ASSERT(
|
||||
address_cast(slab_record->meta_common.chunk) == address_cast(p_tame));
|
||||
|
||||
check_init(
|
||||
[](
|
||||
CoreAlloc* core_alloc,
|
||||
ChunkRecord* slab_record,
|
||||
size_t slab_sizeclass) {
|
||||
ChunkAllocator::dealloc<SharedStateHandle>(
|
||||
core_alloc->get_backend_local_state(),
|
||||
core_alloc->chunk_local_state,
|
||||
slab_record,
|
||||
slab_sizeclass);
|
||||
return nullptr;
|
||||
},
|
||||
slab_record,
|
||||
slab_sizeclass);
|
||||
return;
|
||||
}
|
||||
|
||||
// If p_tame is not null, then dealloc has been call on something
|
||||
// it shouldn't be called on.
|
||||
// TODO: Should this be tested even in the !CHECK_CLIENT case?
|
||||
|
||||
Reference in New Issue
Block a user