size_type total_size_with_header() const { return get_rounded_size ( size_type(sizeof(Header)) , size_type(::boost::alignment_of<block_header<size_type> >::value)) + total_size(); }
std::size_t total_size_with_header() const { return get_rounded_size ( sizeof(Header) , detail::alignment_of<block_header>::value) + total_size(); }
//!Allocates several blocks of nodes. Can throw void priv_alloc_block(size_type num_blocks = 1) { if(!num_blocks) return; size_type blocksize = get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value); try{ for(size_type i = 0; i != num_blocks; ++i){ //We allocate a new NodeBlock and put it as first //element in the free Node list char *pNode = reinterpret_cast<char*> (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t))); char *pBlock = pNode; m_blocklist.push_front(get_block_hook(pBlock, blocksize)); //We initialize all Nodes in Node Block to insert //them in the free Node list for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){ m_freelist.push_front(*new (pNode) node_t); } } } catch(...){ //to-do: if possible, an efficient way to deallocate allocated blocks throw; } }
//!Deallocates all the free blocks of memory. Never throws void deallocate_free_blocks() { typedef typename free_nodes_t::iterator nodelist_iterator; typename blockslist_t::iterator bit(m_blocklist.before_begin()), it(m_blocklist.begin()), itend(m_blocklist.end()); free_nodes_t backup_list; nodelist_iterator backup_list_last = backup_list.before_begin(); //Execute the algorithm and get an iterator to the last value size_type blocksize = get_rounded_size (m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value); while(it != itend){ //Collect all the nodes from the block pointed by it //and push them in the list free_nodes_t free_nodes; nodelist_iterator last_it = free_nodes.before_begin(); const void *addr = get_block_from_hook(&*it, blocksize); m_freelist.remove_and_dispose_if (is_between(addr, blocksize), push_in_list(free_nodes, last_it)); //If the number of nodes is equal to m_nodes_per_block //this means that the block can be deallocated if(free_nodes.size() == m_nodes_per_block){ //Unlink the nodes free_nodes.clear(); it = m_blocklist.erase_after(bit); mp_segment_mngr_base->deallocate((void*)addr); } //Otherwise, insert them in the backup list, since the //next "remove_if" does not need to check them again. else{ //Assign the iterator to the last value if necessary if(backup_list.empty() && !m_freelist.empty()){ backup_list_last = last_it; } //Transfer nodes. This is constant time. backup_list.splice_after ( backup_list.before_begin() , free_nodes , free_nodes.before_begin() , last_it , free_nodes.size()); bit = it; ++it; } } //We should have removed all the nodes from the free list BOOST_ASSERT(m_freelist.empty()); //Now pass all the node to the free list again m_freelist.splice_after ( m_freelist.before_begin() , backup_list , backup_list.before_begin() , backup_list_last , backup_list.size()); }
static Header *to_first_header(block_header<size_type> *bheader) { Header * hdr = reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) - get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value))); //Some sanity checks return hdr; }
static block_header<size_type> *from_first_header(Header *header) { block_header<size_type> * hdr = reinterpret_cast<block_header<size_type>*>(reinterpret_cast<char*>(header) + get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value))); //Some sanity checks return hdr; }
static Header *to_first_header(block_header *bheader) { Header * hdr = reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) - get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value)); //Some sanity checks return hdr; }
static block_header *from_first_header(Header *header) { block_header * hdr = reinterpret_cast<block_header*>(reinterpret_cast<char*>(header) + get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value)); //Some sanity checks return hdr; }
static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn) { block_header * hdr = reinterpret_cast<block_header*>(detail::char_ptr_cast(value) - get_rounded_size(sizeof(block_header), algn)); (void)sz; //Some sanity checks assert(hdr->m_value_alignment == algn); assert(hdr->m_value_bytes % sz == 0); return hdr; }
static block_header<size_type> *block_header_from_value(const void *value, std::size_t sz, std::size_t algn) { block_header * hdr = const_cast<block_header*> (reinterpret_cast<const block_header*>(reinterpret_cast<const char*>(value) - get_rounded_size(sizeof(block_header), algn))); (void)sz; //Some sanity checks BOOST_ASSERT(hdr->m_value_alignment == algn); BOOST_ASSERT(hdr->m_value_bytes % sz == 0); return hdr; }
//!Deallocates all used memory. Precondition: all nodes allocated from this pool should //!already be deallocated. Otherwise, undefined behaviour. Never throws void purge_blocks() { //check for memory leaks BOOST_ASSERT(m_allocated==0); size_type blocksize = get_rounded_size (m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value); typename blockslist_t::iterator it(m_blocklist.begin()), itend(m_blocklist.end()), aux; //We iterate though the NodeBlock list to free the memory while(!m_blocklist.empty()){ void *addr = get_block_from_hook(&m_blocklist.front(), blocksize); m_blocklist.pop_front(); mp_segment_mngr_base->deallocate((void*)addr); } //Just clear free node list m_freelist.clear(); }
size_type value_offset() const { return get_rounded_size(size_type(sizeof(block_header<size_type>)), size_type(m_value_alignment)); }
size_type name_offset() const { return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char())); }
std::size_t value_offset() const { return get_rounded_size(sizeof(block_header), m_value_alignment); }
std::size_t name_offset() const { return value_offset() + get_rounded_size(m_value_bytes, sizeof_char()); }