/** * \file mem_mgr.txx * \author Dhairya Malhotra, dhairya.malhotra@gmail.com * \date 9-21-2014 * \brief This file contains the definition of a simple memory manager which * uses a pre-allocated buffer of size defined in call to the constructor. */ #include #include #include #include #include namespace pvfmm{ namespace mem{ template uintptr_t TypeTraits::ID(){ return (uintptr_t)&ID; } template bool TypeTraits::IsPOD(){ return false; } #define PVFMMDefinePOD(type) template<> bool inline TypeTraits::IsPOD(){return true;}; PVFMMDefinePOD(char); PVFMMDefinePOD(float); PVFMMDefinePOD(double); PVFMMDefinePOD(int); PVFMMDefinePOD(long long); PVFMMDefinePOD(unsigned long); PVFMMDefinePOD(char*); PVFMMDefinePOD(float*); PVFMMDefinePOD(double*); #undef PVFMMDefinePOD MemoryManager::MemHead* MemoryManager::GetMemHead(void* p){ static uintptr_t alignment=MEM_ALIGN-1; static uintptr_t header_size=(uintptr_t)(sizeof(MemoryManager::MemHead)+alignment) & ~(uintptr_t)alignment; return (MemHead*)(((char*)p)-header_size); } size_t MemoryManager::new_node() const{ if(node_stack.empty()){ node_buff.resize(node_buff.size()+1); node_stack.push(node_buff.size()); } size_t indx=node_stack.top(); node_stack.pop(); assert(indx); return indx; } void MemoryManager::delete_node(size_t indx) const{ assert(indx); assert(indx<=node_buff.size()); MemNode& n=node_buff[indx-1]; n.free=false; n.size=0; n.prev=0; n.next=0; n.mem_ptr=NULL; node_stack.push(indx); } template T* aligned_new(size_t n_elem, const MemoryManager* mem_mgr){ if(!n_elem) return NULL; static MemoryManager def_mem_mgr(0); if(!mem_mgr) mem_mgr=&def_mem_mgr; T* A=(T*)mem_mgr->malloc(n_elem, sizeof(T)); if(!TypeTraits::IsPOD()){ // Call constructors //printf("%s\n", __PRETTY_FUNCTION__); #pragma omp parallel for for(size_t i=0;i void aligned_delete(T* A, const MemoryManager* mem_mgr){ if (!A) return; if(!TypeTraits::IsPOD()){ // Call destructors //printf("%s\n", __PRETTY_FUNCTION__); MemoryManager::MemHead* mem_head=MemoryManager::GetMemHead(A); size_t type_size=mem_head->type_size; size_t n_elem=mem_head->n_elem; for(size_t i=0;i~T(); } }else{ #ifndef NDEBUG MemoryManager::MemHead* mem_head=MemoryManager::GetMemHead(A); size_t type_size=mem_head->type_size; size_t n_elem=mem_head->n_elem; size_t size=n_elem*type_size; #pragma omp parallel for for(size_t i=0;ifree(A); } void* memcopy( void * destination, const void * source, size_t num){ if(destination==source || num==0) return destination; return memcpy ( destination, source, num ); } }//end namespace }//end namespace