diff --git a/emper/MemoryManager.hpp b/emper/MemoryManager.hpp index 70041094077e4b6c2cc99835fd01dfe20d319c35..5447ccc3a1f4307510f181af000f8779a7c273ad 100644 --- a/emper/MemoryManager.hpp +++ b/emper/MemoryManager.hpp @@ -14,6 +14,8 @@ class MemoryManager { private: const workerid_t workerCount; + adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE>** workerExclusiveQueues; + adt::WsClQueue<void*, WS_QUEUE_SIZE>** queues; static thread_local adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE> workerExclusiveQueue; @@ -32,6 +34,8 @@ class MemoryManager { public: MemoryManager(Runtime& runtime); + ~MemoryManager(); + auto getMemory(bool* malloced) -> void* { *malloced = false; void* memory = workerExclusiveQueue.get(); @@ -88,7 +92,28 @@ template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::MemoryManager(Runtime& runtime) : workerCount(runtime.getWorkerCount()) { queues = new adt::WsClQueue<void*, WS_QUEUE_SIZE>*[workerCount]; + workerExclusiveQueues = + new adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE>*[workerCount]; - auto newWorkerHook = [this](workerid_t workerId) { queues[workerId] = &queue; }; + auto newWorkerHook = [this](workerid_t workerId) { + workerExclusiveQueues[workerId] = &workerExclusiveQueue; + queues[workerId] = &queue; + }; runtime.addNewWorkerHook(newWorkerHook); } + +template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> +MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::~MemoryManager() { + for (workerid_t i = 0; i < workerCount; ++i) { + auto* queue = workerExclusiveQueues[i]; + while (auto* mem = queue->get()) free(mem); + } + delete workerExclusiveQueues; + + for (workerid_t i = 0; i < workerCount; ++i) { + auto* queue = queues[i]; + void* mem; + while (queue->popBottom(&mem)) free(mem); + } + delete queues; +}