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

📄 pooled_allocator.h

📁 简单的动态内存管理程序源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
    // Determine the size of the  last chunk and double the size for    // the new chunk    // tot_chunk_size = header + bit_vec_sz + elements    //     const int& header   = sizeof(Chunk);    int elements;    int num_of_elements;    //     if (last_chunk) {      // How much space was used  for elements in the last chunk?  Use      // this number to compute the number of pages allocated for that      // chunk.      num_of_elements = 2*last_chunk->get_num_of_elements();      elements =	num_of_elements*last_chunk->get_element_size();      // get the next segment in the series    } else {      // if no chunks have been allocated      // request enough space for 4 objects      num_of_elements = initial_num_of_elems;      elements = initial_num_of_elems*element_size;      // start with the first segment in the series.      // given the size of memory    }    const int& bit_vec_sz = num_of_elements/8 + 1;    // Now use elements to  finish determining the requested number of    // requested pages    const int& temp_size = header + bit_vec_sz + elements;    request_pages = temp_size/page_size;    if (temp_size%page_size) {      // if it does not divide exactly, round up      request_pages++;    }    return request_pages;  };  // Pool::compute_chunk_pages()  ////////////////////////////////////////////////////////////////////  //////           find_shared_memory(int requested_pages)  ////////////////////////////////////////////////////////////////////  //////          //////        requested_pages - find  this number of available pages  //////                          from the  shared memory  segments to   //////                          use for creating a new chunk.  //////          //////        Returns a  pair containing  the starting page  for the  //////        allocated memory  and a  pointer to the  shared memory  //////        header which contains the allocated pages of memory.  //////          //////        Attach to  memory pages  in the shared  memory segment  //////        series which  are specified by  the alloc_key.  Search  //////        for  the requested  number  of pages.   Memory can  be  //////        continually allocated and freed by other processes, so  //////        start  with the  first  segment and  work through  the  //////        list.   Later,  other  arrangements of  shared  memory  //////        segment searches can be developed.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   std::pair<mem_space::shared_memory_header_t*,int>  Pool<T,alloc_key,alloc_addr>::find_shared_memory(int requested_pages) {    // Start to  attach to memory  pages in the shared  memory segment    // series which  are specified  by the alloc_key.   Because memory    // can  be continually  allocated  and freed  by other  processes,    // always start with the first  segment and work through the list.    // Later, other arrangements of shared memory segment searches can    // be developed.        int proj_id = 1;		// index  through  the  shared  memory				// segments.    mem_space::memory_index_t mem_idx =	// allocate will attach to the      //      mem.allocate();  // shared memory segment if it      mem.allocate(proj_id);  // shared memory segment if it					// exists, or  create it if it					// does not.          // Access the shared memory header    mem_space::shared_memory_header_t* smh =      static_cast<mem_space::shared_memory_header_t*>(mem_idx.get_memory_ptr());    // smh->print();    // The pool can request variable number of pages from the segment.    // But it can just get full pages.  The chunk can then portion the    // pages out in element portions.    // locate needed memory in shared segment    bool memory_found = false;    int start_page;		// The  start page  num  of the  found				// memory.    while (!memory_found) {      // Does this shared memory segment have the needed memory?      start_page = smh->find_free_pages(requested_pages);      if (start_page == -1) {	// memory not available in this segment, try next segment 	proj_id = smh->get_proj_id() + 1;  	if ((proj_id > mem_space::shared<alloc_key,alloc_addr>::num_of_segments) || 	    (proj_id < 1)) { 	  // 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)); 	}	// Using the  new proj_id, get  the next shared  memory header	// (smh)	mem_space::memory_index_t mem_idx =// 	  mem.allocate(); 	  mem.allocate(proj_id);	// Access the shared memory header	smh =	  static_cast<mem_space::shared_memory_header_t*>(mem_idx.get_memory_ptr());      } else {	memory_found = true;      } // if (start_page == -1)    }  // while (!memory_found)    return std::pair<mem_space::shared_memory_header_t*,int>(smh,start_page);  }; // void* find_shared_memory(int requested_pages)    ////////////////////////////////////////////////////////////////////  //////                   Pool::retrieve_object_ptr()  ////////////////////////////////////////////////////////////////////  //////          //////        obj_idx  -  contains  address  information  about  the  //////        object whose pointer is to be retrieved.  //////          //////        Retrieve  a pointer  to  the object  specified by  the  //////        parameter.  This  function is  intended to be  used by  //////        processes retrieving  an object stored  by a different  //////        process.  //////          //////////////////////////////////////////////////////////////////////  template<class T,// 	   mem_space::allocator_t alloc_type,// 	   mem_space::allocator_key_t alloc_key,//            mem_space::allocator_addr_t alloc_addr> //   unsigned char* //   Pool<T,alloc_type,//        alloc_key,//        alloc_addr>::retrieve_object_ptr(mem_space::memory_index_t obj_idx) {//     // First retrieve the correct shared memory segement w/header//     mem_space::shared_memory_header_t* smh =//       find_shared_segment();// //       find_shared_segment(obj_idx.get_proj_id());//     // Now used the shared memory  header to locate the pointer to the//     // object//     // The memory_index_t values are  set by chunks when they allocate//     // memory in Chunk::allocate().  Extract these values and use them//     // to  find the proper  shared memory  segment, the  specific page//     // within  that segment  and  the element  offset  to compute  the//     // object's address.//     const int& segment_page_num = obj_idx.get_segment_page_num();//     const int& element_offset = obj_idx.get_element_offset();//     int page_offset = smh->get_page_offset(segment_page_num);//     // Now add  the page offset to  the begnning of  the shared memory//     // segment to get the start  of the correct segment page.  Add the//     // element_offset  to get  from  the correct  page  to the  actual//     // element addresss and done.//     return reinterpret_cast<unsigned char*>(smh) + page_offset +//       element_offset;//   };  // Pool::retrieve_object_ptr()    ////////////////////////////////////////////////////////////////////  //////                   Pool::get_map_index()  ////////////////////////////////////////////////////////////////////  //////          //////        Get the  allocator main index map.  This  map, if set,  //////        contains  a mapping of  specifically set  objects with  //////        index informaton to obtain the memory addresses.  //////          //////        Always store  the object map index  information in the  //////        segment with proj_id == 1.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   mem_space::map_index_t   Pool<T,alloc_key,       alloc_addr>::get_map_index(void) {        // Retrieve the shared memory segement w/header for proj_id = 1.    mem_space::shared_memory_header_t* smh =      find_shared_segment(1);//       find_shared_segment();    // return the index information    return smh->get_map_index();  };  // get_map_index(void)     ////////////////////////////////////////////////////////////////////  //////                   Pool::set_map_index()  ////////////////////////////////////////////////////////////////////  //////          //////        obj_idx  - contains memory  index information  used to  //////                   retrieve the index map itself.  //////          //////        This  function initializes  the  allocator main  index  //////        map.  The  map then contains  a mapping of  key values  //////        versus the  index information used  to retrieve offset  //////        pointers to the objects referenced by the key values.  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   void Pool<T,alloc_key,	    alloc_addr>::set_map_index(mem_space::map_index_t					  obj_idx) {    // Retrieve the shared memory segement w/header for proj_id = 1.    mem_space::shared_memory_header_t* smh =      find_shared_segment(1);//       find_shared_segment();    // return the index information    smh->set_map_index(obj_idx);    return;  };  // void set_map_index()  ////////////////////////////////////////////////////////////////////  //////                   Pool::free_chunk()  ////////////////////////////////////////////////////////////////////  //////          //////        Function releases chunk or recycles the chunk.  //////          //////          //////          //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>  void Pool<T,alloc_key,alloc_addr>::free_chunk(Chunk* victim) {    int num_of_segment_pages = victim->get_num_of_segment_pages();    int segment_page_num = victim->get_segment_page_num();    const int& proj_id = victim->get_proj_id();    mem_space::memory_index_t mem_idx =      // 	  mem.allocate();      mem.allocate(proj_id);    // Access the shared memory header    mem_space::shared_memory_header_t* smh =      static_cast<mem_space::shared_memory_header_t*>(mem_idx.get_memory_ptr());    victim->~Chunk();		// Call destructor manually    smh->clear_pages(segment_page_num,num_of_segment_pages); };  // Pool<>::free_chunk(Chunk* victim)    ////////////////////////////////////////////////////////////////////  //////                   Pool::grow()  ////////////////////////////////////////////////////////////////////  //////          //////      Increase  the  current  available  memory in  the  Pool.  //////      Allocate a new 'chunk' and  organize it as a linked list  //////      of elements of size esize.   Pool is created to exist as  //////      an  object allocated  within  a process,  but  not as  a  //////      static object.    //////        //////      Memory  for the  needed chunks  comes from  two possible  //////      sources:  //////          //////             1. An   existing  shared   memory   segment  with  //////                available memory.  //////             2. A  new shared memory  segment must  be created  //////                and used to retrieve the requested memory.    //////          //////      If a previously used  shared memory segment exists which  //////      has  available  memory, the  grow  routine should  first  //////      request memory  from that existing  segment.  Otherwise,  //////      if there are no available shared memory segments or they  //////      exist  but  are  exhausted,  then a  new  shared  memory  //////      segment  should be  allocated and  the memory  should be  //////      retrieved from that new segment.  //////        //////      The  grow routine uses  a static  version of  the shared  //////      class  to retrieve  memory from  the UNIX  shared memory  //////      segment.  //////        //////      Called to increase the amount of available memory in the  //////      memory pool.  Each chunk  represents a set of pages from  //////      a shared memory segment.  //////        //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   void Pool<T,alloc_key,alloc_addr>::grow() {    //    // alloc_key - determines which  series of shared memory segements    //             are accessed to create new chunks.    //    // Pool::grow() does  not return it value.  However,  it creates a    // new chunk which it places on the Pool chunks attribute list.    //    // Assume:    //    Need to allocate  a new chunk.  All current  chunk memory is    //    exhausted.    //        //////////////////////////////////////////////////////////////////    //////            Compute Requested Chunk Pages    //////////////////////////////////////////////////////////////////    const int& requested_pages = compute_chunk_pages();    //////////////////////////////////////////////////////////////////    ///////        Find available memory in shared segment    //////////////////////////////////////////////////////////////////#ifdef DEBUG    std::clog << __FILE__ << ':' << __LINE__  << ':' <<      " Pool<>::grow() " << std::endl;    std::clog.flush();#endif    std::pair<mem_space::shared_memory_header_t*,int>      smh_obj = find_shared_memory(requested_pages);    // Returns  a pair  with a  pointer to  the shared  memory segment    // which has the needed memory pages available,    const int& start_page_num = smh_obj.second;    // and  the starting  page  number  in the  segment  of the  first    // requested page.    mem_space::shared_memory_header_t *smh = smh_obj.first;    smh->mark_pages(start_page_num,requested_pages);    // compute the chunk_offset

⌨️ 快捷键说明

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