📄 pooled_allocator.h
字号:
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 + -