diff --git a/src/mem/pool.h b/src/mem/pool.h index 366e68728..c10a9e71d 100644 --- a/src/mem/pool.h +++ b/src/mem/pool.h @@ -50,7 +50,10 @@ namespace snmalloc T* p = stack.pop(); if (p != nullptr) + { + p->set_in_use(); return p; + } p = memory_provider .template alloc_chunk( @@ -60,14 +63,21 @@ namespace snmalloc p->list_next = list; list = p; + p->set_in_use(); return p; } + /** + * Return to the pool an object previously retrieved by `acquire` + * + * Do not return objects from `extract`. + */ void release(T* p) { // The object's destructor is not run. If the object is "reallocated", it // is returned without the constructor being run, so the object is reused // without re-initialisation. + p->reset_in_use(); stack.push(p); } @@ -80,6 +90,11 @@ namespace snmalloc return p->next; } + /** + * Return to the pool a list of object previously retrieved by `extract` + * + * Do not return objects from `acquire`. + */ void restore(T* first, T* last) { // Pushes a linked list of objects onto the stack. Use to put a linked diff --git a/src/mem/pooled.h b/src/mem/pooled.h index e9a10af70..8d1cfaf3b 100644 --- a/src/mem/pooled.h +++ b/src/mem/pooled.h @@ -17,5 +17,19 @@ namespace snmalloc std::atomic next = nullptr; /// Used by the pool to keep the list of all entries ever created. T* list_next; + std::atomic_flag in_use = ATOMIC_FLAG_INIT; + + public: + void set_in_use() + { + if (in_use.test_and_set()) + error("Critical error: double use of Pooled Type!"); + } + + void reset_in_use() + { + in_use.clear(); + } + }; } // namespace snmalloc \ No newline at end of file