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

📄 pooled_allocator.h

📁 简单的动态内存管理程序源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
    const int& chunk_offset = smh->get_page_offset(start_page_num);    const int& total_chunk_size = requested_pages*page_size;    void* buff = reinterpret_cast<unsigned char*>(smh) +      chunk_offset;    // get the proj_id    const int& proj_id = smh->get_proj_id();    Chunk* n = new(buff)Chunk(element_size,     // element size			      total_chunk_size, // data_segment size 			      proj_id,          // shared mem segment id			      start_page_num);  // Chunk is on this                                                 // page  within the                                                 // shared   memory                                                  // segment   identified                                                //      by   proj_id.                                                // proj_id  ==                                                 // segment page number                                                // start_page_num !=                                                // segment page number    // get the pathname, really same as alloc_key    char pathname[mem_space::name_length];    smh->get_key(pathname);    n->set_pathname(pathname);    if (chunks) {      // Some chunks have already been allocated      Chunk* last_chunk=get_last_chunk();      last_chunk->set_next(n);      n->set_prev(last_chunk);      // set the chunk's first global element number based on previous      // chunk      int global_first_element = last_chunk->get_first_elem_num() +	last_chunk->get_num_of_elements();      n->set_first_elem_num(global_first_element);    } else {      // This is the first chunk to be allocated      n->set_next(0);      n->set_prev(0);      // set the chunk's first global element number to 0      n->set_first_elem_num(0);      chunks = n;    }  }; // Pool::grow()    ////////////////////////////////////////////////////////////////////  //////                       Pool::allocate()  ////////////////////////////////////////////////////////////////////  //////          //////        num_of_elements - memory for num_of_elements  //////        alloc_key - key used to specify which series of shared  //////                    memory   segments.  Segment   series   are   //////                    futher   singled  out   by  their   unique   //////                    proj_id's.  //////          //////        allocate  adjusts  pointers in  the  memory chunk  and  //////        returns a pointer to the start of the allocated memory  //////          //////////////////////////////////////////////////////////////////// template<class T,	   mem_space::allocator_key_t alloc_key,           mem_space::allocator_addr_t alloc_addr>   mem_space::memory_index_t  Pool<T,alloc_key,alloc_addr>::alloc(const int num_of_elements) {    // Let the upper level functions attempt to catch.    if (chunks==0) {      grow();    }  // if (chunks==0)    // lock the segments to prevent similar concurrent searches    if (!chunks)      std::cerr << __FILE__ << ':' << __LINE__  << ':' << " Chunks is still 0."		<< std::endl;    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());    std::pair<Chunk*,int> obj_pair = find(num_of_elements);    while (!obj_pair.first) {      // The find was unsucessful.  Try to grow some more memory      // unlock the segment page      smh->unlock(chunks->get_segment_page_num());      grow();      // Search again      // lock the segments to prevent similar concurrent searches      // lock on the first page      proj_id = chunks->get_proj_id();      mem_idx = mem.allocate(proj_id);      smh =	static_cast<mem_space::shared_memory_header_t*>(mem_idx.get_memory_ptr());      smh->lock(chunks->get_segment_page_num());      obj_pair = find(num_of_elements);      if (!obj_pair.first) {	// still a problem, give up and throw	  std::clog << "Error: " << __FILE__ << ':' << __LINE__ ;	  std::clog << ": Pool::alloc(): Not enough memory for " <<	    num_of_elements << " elements." << std::endl;	  throw (Alloc_Exception::alloc_exception(0));      }  // if (!obj_pair.first)    }  // while (!obj_pair.first)    // We now have access to the requested memory    // mark it as in service    Chunk* this_chunk = obj_pair.first;    const int& global_element_number = obj_pair.second;//     this_chunk->mark(global_element_number,num_of_elements);    const mem_space::memory_index_t& obj_idx =      this_chunk->allocate(global_element_number,num_of_elements);    int count = smh->get_ref_count();    smh->set_ref_count(count + num_of_elements);//     ref_count += num_of_elements;  // Used by the destructor#ifdef DEBUG    std::cerr << __FILE__ << ':' << __LINE__  <<':' <<       " Pool<>::alloc() ref_count + num_of_elements: " <<      std::endl;    std::cerr << count <<  " + " << num_of_elements << " = " <<      count + num_of_elements << std::endl;     mem_space::memory_index_t* obj = new mem_space::memory_index_t(obj_idx);     void* p = obj->get_memory_ptr();     std::cerr << "Allocated memory at address: " <<       (const void*) p << std::endl;#endif        // After marking, unlock the chunk    smh->unlock(chunks->get_segment_page_num());    return obj_idx;  }; // Pool::alloc()  ////////////////////////////////////////////////////////////////////  //////                       Pool::free()  ////////////////////////////////////////////////////////////////////  //////          //////        p - points to the memory to be freed.  //////        num_of_elements - how many elements starting at p  //////          //////        Release memory 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>::free(unsigned char* p, int num_of_elements) {   // Free called on existing memory, make sure chunks ptr valid.   if (chunks==0) {     grow();   }  // if (chunks==0)   std::pair<Chunk*,int> obj_pair = find_chunk(p);   if (obj_pair.first) {  // if a valid chunk found     Chunk* this_chunk = obj_pair.first;     const int& global_element_num = obj_pair.second +       this_chunk->get_first_elem_num();     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(this_chunk->get_segment_page_num());     int count = smh->get_ref_count();     smh->set_ref_count(count - num_of_elements);//     ref_count -= num_of_elements;  // Used by the destructor#ifdef DEBUG     std::cerr << __FILE__ << ':' << __LINE__	       << ": Pool<>::free() ref_count - num_of_elements: " <<       std::endl;     std::cerr << count <<  " - " << num_of_elements << " = " <<       count-num_of_elements << std::endl;     std::cerr << "Freed memory at address: " << (void*) p << std::endl;#endif     this_chunk->free(global_element_num,num_of_elements);     smh->unlock(this_chunk->get_segment_page_num());   } else {     std::cerr << __FILE__ << ':' << __LINE__	       << ": Pool<>::free() : valid chunk not found." <<       std::endl;     std::cerr << __FILE__ << ':' << __LINE__	       << " *p : " << std::hex << p 	       << " : num_of_elements : " << std::dec << num_of_elements 	       << std::endl;     std::cerr << "Memory at address: " << (void*) p << std::endl;     std::cerr << "Chunks value: " << (void*) chunks << std::endl;   }    return;  };  // Pool::free()  /////////////////////////////////////////////////////////////////////////////  //////                           Class Pool_alloc  /////////////////////////////////////////////////////////////////////////////  //////          //////        This class provide the generic allocator interface to the   //////        outside world.  //////          //////          /////////////////////////////////////////////////////////////////////////////    // Define template type parameters as follows  //     T - The type of object to be allocated.  (ie the allocator will hold ints)  //     U - Defines the type of allocator, expected to be mem_space::allocator_t.  Currently,  //         only sharedpooled is defined.  In the future, persistent,       template<class T,	   mem_space::allocator_key_t alloc_key,	   mem_space::allocator_addr_t alloc_addr=0>  class Pool_alloc {  protected:    Pool<T,	 alloc_key,	 alloc_addr> mem;		// pool of elements of sizeof(T)  public:    typedef T value_type;    typedef std::size_t size_type;    typedef std::ptrdiff_t difference_type;        typedef T* pointer;    typedef const T* const_pointer;        typedef T& reference;    typedef const T& const_reference;        pointer address(reference r) const { return &r; }    const_pointer address(const_reference r) const {return &r;}        // constructor    Pool_alloc() :      mem() {};        // copy constructor    template<class J,	     mem_space::allocator_key_t alloc_key2,	     mem_space::allocator_addr_t alloc_addr2>    Pool_alloc(const Pool_alloc<J,	       alloc_key2,	       alloc_addr2>& t) { };    // destructor    virtual ~Pool_alloc() throw() {    };    // equality operator    bool operator==(const Pool_alloc<T,		    alloc_key,		    alloc_addr>& t) const {      bool flag = false;      if (mem == t.mem)	flag = true;      return true;      };    // inequality operator    bool operator!=(const Pool_alloc<T,		    alloc_key,		    alloc_addr>& t) const {      return !(mem == t.mem);    };        // original allocate function for the allocator interface    // space for n Ts    virtual pointer allocate(size_type n, const_pointer hint=0);	    virtual mem_space::memory_index_t    allocate_with_index(size_type n);	// space for n Ts    virtual Chunk* get_chunks_list() {      return mem.get_chunks_list();    };    virtual void set_chunks_list(Chunk* val) {      mem.set_chunks_list(val);      return;    };    // deallocate n Ts, don't destroy    virtual void deallocate(pointer p,size_type n);         // initialize *p by val    void construct(pointer p, const_reference val) { new(p) T(val); }     void destroy(pointer p) { p->~T(); } // destroy *p but don't deallocate        size_type max_size() const throw();        template<class J>    // in effect: typedef Pool_alloc<U> other    struct rebind { typedef Pool_alloc<J,				       alloc_key,				       alloc_addr> other; };  };  // class Pool_alloc    //   // static variable declaration for Pool//   template<class T,// 	   mem_space::allocator_t alloc_type,// 	   mem_space::allocator_key_t alloc_key,// 	   mem_space::allocator_addr_t alloc_addr=0>//   Pool<T,alloc_type, alloc_key, alloc_addr>//   Pool_alloc<T, alloc_type, alloc_key, alloc_addr>::mem(sizeof(T));      ////////////////////////////////////////////////////////////////////  //////  //////  Memory allocation starts here  //////  ////////////////////////////////////////////////////////////////////    template<class T,	   mem_space::allocator_key_t alloc_key,	   mem_space::allocator_addr_t alloc_addr>  T* Pool_alloc<T,		alloc_key,		alloc_addr>::allocate(size_type n, const_pointer hint) {#ifdef SHARED_MEMORY_MESG    std::cerr << "allocate: " << n << " objects ********\n";#endif    mem_space::memory_index_t obj_idx =      mem.alloc(n);    return reinterpret_cast<T*>(obj_idx.get_memory_ptr());  }    ////////////////////////////////////////////////////////////////////  //////  //////  Memory allocation starts here  //////  //////  n - how many objects to allocate  //////    //////  Returns a memory_index_t which  contains a pointer to memory  //////  big  enough to  hold n  objects.  The  memory_index_t object  //////  also contains index informaton which allows retrieval of the  //////  allocated memory space.  //////    //////    //////    ////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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