diff --git a/src/mem/corealloc.h b/src/mem/corealloc.h index 7870d73..ecc01b0 100644 --- a/src/mem/corealloc.h +++ b/src/mem/corealloc.h @@ -416,7 +416,7 @@ namespace snmalloc #ifdef SNMALLOC_TRACING std::cout << "Handling remote" << std::endl; #endif - handle_dealloc_remote(entry, p, need_post); + handle_dealloc_remote(entry, r.first.as_void(), need_post); } if (need_post) @@ -435,7 +435,7 @@ namespace snmalloc */ void handle_dealloc_remote( const MetaEntry& entry, - FreeObject::QueuePtr p, + CapPtr p, bool& need_post) { // TODO this needs to not double count stats @@ -716,6 +716,9 @@ namespace snmalloc bool flush(bool destroy_queue = false) { SNMALLOC_ASSERT(attached_cache != nullptr); + // TODO: Placeholder + auto domesticate = [](FreeObject::QueuePtr p) + SNMALLOC_FAST_PATH_LAMBDA { return p; }; if (destroy_queue) { @@ -724,10 +727,10 @@ namespace snmalloc while (p != nullptr) { bool need_post = true; // Always going to post, so ignore. - auto n = p->atomic_read_next(key_global); + auto n = p->atomic_read_next(key_global, domesticate); auto& entry = SharedStateHandle::Pagemap::get_metaentry( backend_state_ptr(), snmalloc::address_cast(p)); - handle_dealloc_remote(entry, p, need_post); + handle_dealloc_remote(entry, p.as_void(), need_post); // XXX n is not known to be domesticated p = n; } diff --git a/src/mem/freelist.h b/src/mem/freelist.h index dd15f10..0b882a3 100644 --- a/src/mem/freelist.h +++ b/src/mem/freelist.h @@ -127,31 +127,40 @@ namespace snmalloc #endif public: - QueuePtr atomic_read_next(const FreeListKey& key) + template< + SNMALLOC_CONCEPT(capptr::ConceptBound) BView = typename BQueue:: + template with_wildness, + typename Domesticator> + HeadPtr + atomic_read_next(const FreeListKey& key, Domesticator domesticate) { - auto n = FreeObject::decode_next( + auto n_wild = FreeObject::decode_next( address_cast(&this->next_object), this->atomic_next_object.load(std::memory_order_acquire), key); + auto n_tame = domesticate(n_wild); #ifdef SNMALLOC_CHECK_CLIENT - // XXX n is not known to be domesticated here - if (n != nullptr) + if (n_tame != nullptr) { - n->check_prev(signed_prev(address_cast(this), address_cast(n), key)); + n_tame->check_prev( + signed_prev(address_cast(this), address_cast(n_tame), key)); } -#else - UNUSED(key); #endif - return n; + return n_tame; } /** * Read the next pointer */ - QueuePtr read_next(const FreeListKey& key) + template< + SNMALLOC_CONCEPT(capptr::ConceptBound) BView = typename BQueue:: + template with_wildness, + typename Domesticator> + HeadPtr + read_next(const FreeListKey& key, Domesticator domesticate) { - return FreeObject::decode_next( - address_cast(&this->next_object), this->next_object, key); + return domesticate(FreeObject::decode_next( + address_cast(&this->next_object), this->next_object, key)); } /** @@ -228,10 +237,18 @@ namespace snmalloc } /** - * Decode next. While traversing a queue, BView and BQueue here will - * often be equal (i.e., CBAllocExportWild) rather than dichotomous. - * However, we do occasionally decode an actual head pointer, so be - * polymorphic here. + * Decode next. While traversing a queue, BView and BQueue here will often + * be equal (i.e., CBAllocExportWild) rather than dichotomous. However, + * we do occasionally decode an actual head pointer, so be polymorphic here. + * + * TODO: We'd like, in some sense, to more tightly couple or integrate this + * into to the domestication process. We could introduce an additional + * state in the capptr_bounds::wild taxonomy (e.g, Obfuscated) so that the + * Domesticator-s below have to call through this function to get the Wild + * pointer they can then make Tame. It's not yet entirely clear what that + * would look like and whether/how the encode_next side of things should be + * exposed. For the moment, obfuscation is left encapsulated within + * FreeObject and we do not capture any of it statically. */ template< SNMALLOC_CONCEPT(capptr::ConceptBound) BView, @@ -391,7 +408,10 @@ namespace snmalloc FreeObject::HeadPtr take(const FreeListKey& key) { auto c = curr; - auto next = curr->read_next(key); + // TODO: Placeholder + auto domesticate = [](FreeObject::QueuePtr p) + SNMALLOC_FAST_PATH_LAMBDA { return p; }; + auto next = curr->read_next(key, domesticate); Aal::prefetch(next.unsafe_ptr()); curr = next; diff --git a/src/mem/remoteallocator.h b/src/mem/remoteallocator.h index 2e4e735..2be554f 100644 --- a/src/mem/remoteallocator.h +++ b/src/mem/remoteallocator.h @@ -102,13 +102,18 @@ namespace snmalloc /** * Returns the front message, or null if not possible to return a message. */ - std::pair, bool> + std::pair< + FreeObject::HeadPtr, + bool> dequeue(const FreeListKey& key) { + auto domesticate = [](FreeObject::QueuePtr p) + SNMALLOC_FAST_PATH_LAMBDA { return p; }; invariant(); - FreeObject::QueuePtr first = front; + FreeObject::HeadPtr + first = domesticate(front); FreeObject::QueuePtr next = - first->atomic_read_next(key); + first->atomic_read_next(key, domesticate); if (next != nullptr) {