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