⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pooled_allocator.h

📁 简单的动态内存管理程序源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
	   mem_space::allocator_addr_t alloc_addr=0>   Chunk* Pool<T,alloc_key,alloc_addr>::chunks = 0; // list of allocated chunks      ////////////////////////////////////////////////////////////////////  //////                    Class Pool  ////////////////////////////////////////////////////////////////////  //////          //////        Pool Function Definitions start here.  //////          ////////////////////////////////////////////////////////////////////    // constructor template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>//   Pool<alloc_type,alloc_key,alloc_addr>::Pool(const int& size) :  Pool<T,alloc_key,alloc_addr>::Pool() :    element_size(sizeof(T)),    mem(pooled_allocator::num_of_pages,	pooled_allocator::page_size) {#ifdef DEBUG   std::cerr << __FILE__ << ':' << __LINE__ << ':' <<     " Pool() : constructor. " << std::endl;#endif   // instantiate the first chunk on the chunk list   if (!chunks) {     grow();   }   // chunks=0;//    ref_count = 0;  }; // constructor  // destructor template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   Pool<T,alloc_key,alloc_addr>::~Pool() {   // mem.~shared();//    if (chunks) {//      int proj_id = chunks->get_proj_id();//      mem_space::memory_index_t mem_idx = mem.allocate(proj_id);//      mem_space::shared_memory_header_t* smh =//        static_cast<mem_space::shared_memory_header_t*>(mem_idx.get_memory_ptr());//      smh->lock(chunks->get_segment_page_num());//      int count = smh->get_ref_count();//      smh->set_ref_count(count-ref_count);//      smh->unlock(chunks->get_segment_page_num());// #ifdef DEBUG//      std::cerr << __FILE__ << ':' << __LINE__// 	       << ": Pool<>::~Pool() count - ref_count: " <<//        std::endl;//      std::cerr << count <<  " - " << ref_count << " = " <<//        count-ref_count << std::endl;// #endif//    } }; // destructor    // copy constructor template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   Pool<T,alloc_key,alloc_addr>::Pool(const Pool<T,				     alloc_key,				     alloc_addr>& t) :    element_size(t.element_size),    mem(pooled_allocator::num_of_pages,	pooled_allocator::page_size) {//    ref_count = 0;   // chunks=t.chunks;  }; // copy constructor    // assignment operator template<class T,	  mem_space::allocator_key_t alloc_key,	  mem_space::allocator_addr_t alloc_addr>  Pool<T,alloc_key,      alloc_addr>::Pool<T,alloc_key,			alloc_addr>& Pool<T,					  alloc_key,					  alloc_addr>::operator=(const Pool<T,								 alloc_key,alloc_addr>& t) {//     if (this != &t) {		// avoid self assignment: t=t//       chunks=t.chunks;//     }    return *this;  }; // assignment operator  // equality operator template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>  bool Pool<T,alloc_key,alloc_addr>::operator==(const Pool<T,					       alloc_key,					       alloc_addr>& t) const {    bool return_val=true;    Chunk* this_chunk = chunks;    Chunk* other_chunk = t.chunks;    if (element_size!=t.element_size)      return_val=false;    // test the chunk lists for equality    while ((return_val) && (this_chunk) && (other_chunk)) {      if (!(*this_chunk==*other_chunk))	return_val=false;      else {	this_chunk = this_chunk->get_next();	other_chunk = other_chunk->get_next();      }    }    return return_val;  };  // Pool<T,alloc_type,alloc_key,alloc_addr>::operator==()    ////////////////////////////////////////////////////////////////////  //////                   Pool::get_last_chunk()  ////////////////////////////////////////////////////////////////////  //////          //////        Retrieve the last chunk on the list, return 0 if none.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   Chunk* Pool<T,alloc_key,alloc_addr>::get_last_chunk() {    // Retrieve the last chunk on the list, return 0 if none.    Chunk* last_chunk = chunks;    // if chunks have already been allocated    // get last chunk and square previous request    while ((last_chunk) && (last_chunk->get_next())) {      last_chunk = last_chunk->get_next();    }    return last_chunk;  }; // Chunk* Pool::get_last_chunk()  ////////////////////////////////////////////////////////////////////  //////           Chunk* Pool::find_chunk()  ////////////////////////////////////////////////////////////////////  //////          //////        global_element_num   -  chunk  sought   contains  this  //////                                element number.  //////          //////        Returns the chunk pointer if found, 0 otherwise.  //////          ////////////////////////////////////////////////////////////////////  // find chunk associated with global_element_num template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   Chunk* Pool<T,alloc_key,alloc_addr>::find_chunk(int global_element_num) {    bool found = false;    Chunk* current_chunk = chunks;    while((!found) && (current_chunk != 0)) {      const int& lower_bound = current_chunk->get_first_elem_num();      const int& upper_bound = lower_bound +	current_chunk->get_num_of_elements();      if ((lower_bound <= global_element_num) &&	  (global_element_num < upper_bound))	found = true;      else	current_chunk = current_chunk->get_next();    }    return current_chunk;  };  // Chunk* Pool::find_chunk(int global_element_num)  ////////////////////////////////////////////////////////////////////  //////           Pool::find_chunk(const unsigned char* p)  ////////////////////////////////////////////////////////////////////  //////          //////        p  -  pointer to  allocated  memory.    //////          //////        Find the chunk and element number corresponding to the  //////        pointer,  p.  Returns  a pair  with a  pointer  to the  //////        corresponding chunk and the element number within that  //////        chunk.  If not found, return pair<>(0,-1).  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   std::pair<Chunk*,int> Pool<T,			     alloc_key,			     alloc_addr>::find_chunk(const unsigned char* p) {    bool found = false;    Chunk* current_chunk = chunks;    int element_num;    while((!found) && (current_chunk != 0)) {      element_num =	current_chunk->pointer_to_element_num(p);      if (element_num != -1)	found = true;      else	current_chunk = current_chunk->get_next();    }  // while((!found) && (current_chunk != 0))    return std::pair<Chunk*,int>(current_chunk,element_num);  };  // std::pair<Chunk*,int> find_chunk(const unsigned char* p)  ////////////////////////////////////////////////////////////////////  //////           int Pool::find()  ////////////////////////////////////////////////////////////////////  //////          //////        num_of_elements  -  finds  free, available  memory  to  //////        store this number of elements.  //////          //////        Returns  the  starting  global  element  number  which  //////        indicates  the beginning of  the available  space.  If  //////        the memory  is unavailable,  returns (0,-1).  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   std::pair<Chunk*,int> Pool<T,alloc_key,alloc_addr>::find(int num_of_elements) {    // Search through the list of chunks to find the requested num_of_elements.    Chunk* current_chunk = chunks;    int start_element=-1;    while ((current_chunk != 0)&&(start_element == -1)) {      // The chunk find routine returns the global block number if the      // element is in this chunk, -1 otherwise.      start_element = current_chunk->find(num_of_elements);      if (start_element == -1) {	// memory was not available in the current chunk, try next	if (!current_chunk->get_next()) {	  // end of the line, try to grow more	  grow();	}	if (current_chunk->get_next()) {	  current_chunk = current_chunk->get_next();	} else {	  // Memory appears to be exhausted for this shared	  // segment, throw.	  std::clog << "Error: " << __FILE__ << ':' << __LINE__ ;	  std::clog << ": project id out of range (1 <= proj_id < 128): "		    << std::endl;	  throw (Alloc_Exception::mem_exhausted_exception(0));	}      }    }    return std::pair<Chunk*,int>(current_chunk,start_element);  };  // int Pool::find(int num_of_elements)  ////////////////////////////////////////////////////////////////////  //////           void Pool::mark()  ////////////////////////////////////////////////////////////////////  //////          //////        start_element   - global first  element  number of set  //////                          of elements to be marked.  //////        num_of_elements - how many elements to be marked.  //////          //////        Mark elements  as in use.   The elements may  NOT span  //////        more than one chunk.  This is due to the bytes used by  //////        the  header information  which  prevents a  contiguous  //////        allocation of memory  across multiple chunks.  Chunks,  //////        however,  can be  composed  of multiple  pages from  a  //////        segment,  and  the  allocated  memory can  span  those  //////        subpages which do not have header information.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   void Pool<T,alloc_key,alloc_addr>::mark(int global_start_element,					int num_of_elements) {    // elements  can NOT  be allocated  across chunks,  so we  must be    // working within one chunk.  Find  it and mark the elements.  The    // chunk routines recieve global_start_element addresses.   Chunk* current_chunk = find_chunk(global_start_element);   if (current_chunk)     current_chunk->mark(global_start_element,num_of_elements);    return;  };  // void mark(int start_element,int num_of_elements)  ////////////////////////////////////////////////////////////////////  //////           void Pool::clear()  ////////////////////////////////////////////////////////////////////  //////          //////        start_element   - global first  element  number of set  //////                          of elements to be cleared.  //////        num_of_elements - how many elements to be cleared.  //////          //////        Clear elements for reuse.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   void Pool<T,alloc_key,alloc_addr>::clear(int global_start_element,					 int num_of_elements) {   // elements  can NOT  be allocated  across chunks,  so we  must be   // working within one chunk.  Find it and clear the elements.  The   // chunk routines recieve global_start_element addresses.   Chunk* current_chunk = find_chunk(global_start_element);   if (current_chunk)     current_chunk->clear(global_start_element,num_of_elements);        return;  };  // void clear(int start_element,int num_of_elements)  ////////////////////////////////////////////////////////////////////  //////              Pool::compute_chunk_pages()  ////////////////////////////////////////////////////////////////////  //////          //////        Determine the size of a new chunk to be created.  Find  //////        the last  chunk which was created.  That  chunk, if it  //////        exists, contains information which will help to create  //////        the next  chunk.  For example, if the  last chunk used  //////        by  this process contained  num_pages, the  next chunk  //////        should  contain  2*num_pages.   If  no  chunk  exists,  //////        enough  space is  allocated  for initial_num_of_elems.  //////        The function automatically computes the required pages  //////        for element storage plus the regular chunk overhead.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   int Pool<T,alloc_key,alloc_addr>::compute_chunk_pages() {    int request_pages;    Chunk* last_chunk = get_last_chunk();    //     // The total size of the last  chunk is used to determine what the    // current requested chunk size should be.    // 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -