| 37 | } |
| 38 | |
| 39 | void DefaultMemoryManager::cleanDeviceMemoryManager(int device) { |
| 40 | if (this->debug_mode) { return; } |
| 41 | |
| 42 | // This vector is used to store the pointers which will be deleted by |
| 43 | // the memory manager. We are using this to avoid calling free while |
| 44 | // the lock is being held because the CPU backend calls sync. |
| 45 | vector<void *> free_ptrs; |
| 46 | size_t bytes_freed = 0; |
| 47 | DefaultMemoryManager::memory_info ¤t = memory[device]; |
| 48 | { |
| 49 | lock_guard_t lock(this->memory_mutex); |
| 50 | // Return if all buffers are locked |
| 51 | if (current.total_buffers == current.lock_buffers) { return; } |
| 52 | free_ptrs.reserve(current.free_map.size()); |
| 53 | |
| 54 | for (auto &kv : current.free_map) { |
| 55 | size_t num_ptrs = kv.second.size(); |
| 56 | // Free memory by pushing the last element into the free_ptrs |
| 57 | // vector which will be freed once outside of the lock |
| 58 | // for (auto ptr : kv.second) { free_ptrs.emplace_back(pair); } |
| 59 | std::move(begin(kv.second), end(kv.second), |
| 60 | back_inserter(free_ptrs)); |
| 61 | current.total_bytes -= num_ptrs * kv.first; |
| 62 | bytes_freed += num_ptrs * kv.first; |
| 63 | current.total_buffers -= num_ptrs; |
| 64 | } |
| 65 | current.free_map.clear(); |
| 66 | } |
| 67 | |
| 68 | AF_TRACE("GC: Clearing {} buffers {}", free_ptrs.size(), |
| 69 | bytesToString(bytes_freed)); |
| 70 | // Free memory outside of the lock |
| 71 | for (auto *ptr : free_ptrs) { this->nativeFree(ptr); } |
| 72 | } |
| 73 | |
| 74 | DefaultMemoryManager::DefaultMemoryManager(int num_devices, |
| 75 | unsigned max_buffers, bool debug) |
nothing calls this directly
no test coverage detected