svinco Posted March 13, 2017 Report Posted March 13, 2017 Dear all, I implemented a memory manager (implementing the tlm_mm_interface interface). However, whenever I use the manager with TLM, I get loads of memory leaks, that seem to be caused by the new in the allocate method. Does anybody know an alternative implementation of this, or does anybody understand how I could avoid the leaks? What am I doing wrong? Best regards, S. #include <systemc.h> #include <tlm.h> class mem_manager : public tlm::tlm_mm_interface{ public: std::vector<tlm::tlm_generic_payload *> free_list; tlm::tlm_generic_payload * allocate(); void free(tlm::tlm_generic_payload *); tlm::tlm_generic_payload * ptr; private: ~mem_manager(); }; mem_manager::~mem_manager(){ } tlm::tlm_generic_payload * mem_manager::allocate(){ if (!free_list.empty()) { ptr = free_list.back(); free_list.pop_back(); cout<<"free list not empty"<<endl; } else { ptr = new tlm::tlm_generic_payload(this); cout<<"free list empty"<<endl; } return ptr; } void mem_manager::free(tlm::tlm_generic_payload * trans){ free_list.push_back((tlm::tlm_generic_payload *)trans); } Quote
maehne Posted March 14, 2017 Report Posted March 14, 2017 When implementing your own memory manager for TLM payload objects, you have to follow the rules laid down in IEEE Std 1666-2011 clauses 14.5 and 14.6. When you are leaking memory it is because your new operation to allocate a new tlm_generic_payload object has no matching delete operation. As I understand your implementation, you want to pool the allocated objects once they've been created for the rest of the simulation to reuse them after they've been handed back to the memory manager for another allocation. Therefore, the right moment to delete your payload objects is when the memory manager is deleted itself. To achieve this, you have to traverse your free_list in the mem_manager::~mem_manager() destructor and call delete on each entry. Additionally, you have changed the visibility of your memory manager destructor from public to private. This is not good object-oriented design. Also, the generic payload pointer *ptr should not be a member variable but rather a local variable to mem_manager::allocate(). Clause 14.5e) of IEEE Std 1666-2011 states that you should also call the reset member function of your tlm_generic_payload object in order to delete any extensions marked for automatic deletion. I hope these hints help you to resolve your memory management issues! Philipp A Hartmann 1 Quote
svinco Posted March 29, 2017 Author Report Posted March 29, 2017 Thank you very much for your hints - I managed to fix the code and to have 0 memory leaks! Regards, S. Quote
Khushi Posted October 29 Report Posted October 29 hi do we really need a list(vector) here ? can it be just like following ? #include <systemc.h> #include <tlm.h> class mem_manager : public tlm::tlm_mm_interface{ public: tlm::tlm_generic_payload * allocate(); void free(tlm::tlm_generic_payload *); private: ~mem_manager(); }; mem_manager::~mem_manager(){ } tlm::tlm_generic_payload * mem_manager::allocate(){ tlm::tlm_generic_payload * ptr = new tlm::tlm_generic_payload(this); reurn ptr; } void mem_manager::free(tlm::tlm_generic_payload * trans){ delete (trans); } Any comment on this ? Thank you Khushi Quote
Eyck Posted November 19 Report Posted November 19 Basically you can do it this way but calling new/delete might trigger a syscall to get memeory from the kernel. This is an expensive call. Another issue is the potential heap fragmentation which can be avoided when reusing the payload. An example how to do this efficiently can be found here: https://github.com/Minres/SystemC-Components/blob/main/src/sysc/tlm/scc/tlm_mm.h This one does not only uses a pool based allocation strategy rather also to allow automatic data array management. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.