diff options
Diffstat (limited to 'boost/interprocess/allocators/detail/allocator_common.hpp')
-rw-r--r-- | boost/interprocess/allocators/detail/allocator_common.hpp | 121 |
1 files changed, 57 insertions, 64 deletions
diff --git a/boost/interprocess/allocators/detail/allocator_common.hpp b/boost/interprocess/allocators/detail/allocator_common.hpp index ba14d3f64d..eb8fbfc314 100644 --- a/boost/interprocess/allocators/detail/allocator_common.hpp +++ b/boost/interprocess/allocators/detail/allocator_common.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,6 +11,10 @@ #ifndef BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP #define BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP +#if defined(_MSC_VER) +# pragma once +#endif + #include <boost/interprocess/detail/config_begin.hpp> #include <boost/interprocess/detail/workaround.hpp> @@ -26,7 +30,7 @@ #include <boost/container/detail/multiallocation_chain.hpp> #include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp> #include <boost/interprocess/detail/segment_manager_helper.hpp> -#include <boost/move/move.hpp> +#include <boost/move/utility_core.hpp> #include <boost/interprocess/detail/type_traits.hpp> #include <boost/interprocess/detail/utilities.hpp> #include <algorithm> //std::swap @@ -73,7 +77,7 @@ namespace ipcdetail { template<class NodePool> struct get_or_create_node_pool_func { - + //!This connects or constructs the unique instance of node_pool_t //!Can throw boost::interprocess::bad_alloc void operator()() @@ -90,7 +94,7 @@ struct get_or_create_node_pool_func //!object parameters get_or_create_node_pool_func(typename NodePool::segment_manager *mngr) : mp_segment_manager(mngr){} - + NodePool *mp_node_pool; typename NodePool::segment_manager *mp_segment_manager; }; @@ -118,7 +122,7 @@ struct destroy_if_last_link_func //Last link, let's destroy the segment_manager mp_node_pool->get_segment_manager()->template destroy<NodePool>(boost::interprocess::unique_instance); - } + } //!Constructor. Initializes function //!object parameters @@ -173,7 +177,7 @@ class cache_impl ~cache_impl() { this->deallocate_all_cached_nodes(); - ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool)); + ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool)); } NodePool *get_node_pool() const @@ -189,34 +193,29 @@ class cache_impl { //If don't have any cached node, we have to get a new list of free nodes from the pool if(m_cached_nodes.empty()){ - m_cached_nodes = mp_node_pool->allocate_nodes(m_max_cached_nodes/2); + mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes); } - void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.front()); - m_cached_nodes.pop_front(); + void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.pop_front()); return ret; } - multiallocation_chain cached_allocation(size_type n) + void cached_allocation(size_type n, multiallocation_chain &chain) { - multiallocation_chain chain; size_type count = n, allocated(0); BOOST_TRY{ //If don't have any cached node, we have to get a new list of free nodes from the pool while(!m_cached_nodes.empty() && count--){ - void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.front()); - m_cached_nodes.pop_front(); + void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.pop_front()); chain.push_back(ret); ++allocated; } if(allocated != n){ - multiallocation_chain chain2(mp_node_pool->allocate_nodes(n - allocated)); - chain.splice_after(chain.last(), chain2, chain2.before_begin(), chain2.last(), n - allocated); + mp_node_pool->allocate_nodes(n - allocated, chain); } - return boost::move(chain); } BOOST_CATCH(...){ - this->cached_deallocation(boost::move(chain)); + this->cached_deallocation(chain); BOOST_RETHROW } BOOST_CATCH_END @@ -235,7 +234,7 @@ class cache_impl m_cached_nodes.push_front(ptr); } - void cached_deallocation(multiallocation_chain chain) + void cached_deallocation(multiallocation_chain &chain) { m_cached_nodes.splice_after(m_cached_nodes.before_begin(), chain); @@ -262,7 +261,7 @@ class cache_impl void deallocate_all_cached_nodes() { if(m_cached_nodes.empty()) return; - mp_node_pool->deallocate_nodes(boost::move(m_cached_nodes)); + mp_node_pool->deallocate_nodes(m_cached_nodes); } private: @@ -290,7 +289,7 @@ class cache_impl multiallocation_chain chain; chain.splice_after(chain.before_begin(), m_cached_nodes, m_cached_nodes.before_begin(), it, n); //Deallocate all new linked list at once - mp_node_pool->deallocate_nodes(boost::move(chain)); + mp_node_pool->deallocate_nodes(chain); } public: @@ -335,7 +334,7 @@ class array_allocation_impl //!pointed by p can hold. This size only works for memory allocated with //!allocate, allocation_command and allocate_many. size_type size(const pointer &p) const - { + { return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::to_raw_pointer(p))/sizeof(T); } @@ -355,17 +354,20 @@ class array_allocation_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. The elements must be deallocated //!with deallocate(...) - multiallocation_chain allocate_many(size_type elem_size, size_type num_elements) + void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain) { - return this->derived()->get_segment_manager()->allocate_many(sizeof(T)*elem_size, num_elements); + if(size_overflows<sizeof(T)>(elem_size)){ + throw bad_alloc(); + } + this->derived()->get_segment_manager()->allocate_many(elem_size*sizeof(T), num_elements, chain); } //!Allocates n_elements elements, each one of size elem_sizes[i]in a //!contiguous block //!of memory. The elements must be deallocated - multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements) + void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) { - return this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T)); + this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T), chain); } //!Allocates many elements of size elem_size in a contiguous block @@ -374,8 +376,8 @@ class array_allocation_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. The elements must be deallocated //!with deallocate(...) - void deallocate_many(multiallocation_chain chain) - { return this->derived()->get_segment_manager()->deallocate_many(boost::move(chain)); } + void deallocate_many(multiallocation_chain &chain) + { this->derived()->get_segment_manager()->deallocate_many(chain); } //!Returns the number of elements that could be //!allocated. Never throws @@ -457,14 +459,17 @@ class node_pool_allocation_impl (void)hint; typedef typename node_pool<0>::type node_pool_t; node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); - if(count > this->max_size()) + if(size_overflows<sizeof(T)>(count)){ throw bad_alloc(); - else if(Version == 1 && count == 1) + } + else if(Version == 1 && count == 1){ return pointer(static_cast<value_type*> (pool->allocate_node())); - else + } + else{ return pointer(static_cast<value_type*> - (pool->get_segment_manager()->allocate(sizeof(T)*count))); + (pool->get_segment_manager()->allocate(count*sizeof(T)))); + } } //!Deallocate allocated memory. Never throws @@ -495,11 +500,11 @@ class node_pool_allocation_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. Memory allocated with this function //!must be deallocated only with deallocate_one(). - multiallocation_chain allocate_individual(size_type num_elements) + void allocate_individual(size_type num_elements, multiallocation_chain &chain) { typedef typename node_pool<0>::type node_pool_t; node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); - return multiallocation_chain(pool->allocate_nodes(num_elements)); + pool->allocate_nodes(num_elements, chain); } //!Deallocates memory previously allocated with allocate_one(). @@ -518,10 +523,10 @@ class node_pool_allocation_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. Memory allocated with this function //!must be deallocated only with deallocate_one(). - void deallocate_individual(multiallocation_chain chain) + void deallocate_individual(multiallocation_chain &chain) { node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes - (chain.extract_multiallocation_chain()); + (chain); } //!Deallocates all free blocks of the pool @@ -605,14 +610,15 @@ class cached_allocator_impl { (void)hint; void * ret; - if(count > this->max_size()) + if(size_overflows<sizeof(T)>(count)){ throw bad_alloc(); + } else if(Version == 1 && count == 1){ ret = m_cache.cached_allocation(); } else{ - ret = this->get_segment_manager()->allocate(sizeof(T)*count); - } + ret = this->get_segment_manager()->allocate(count*sizeof(T)); + } return pointer(static_cast<T*>(ret)); } @@ -640,8 +646,8 @@ class cached_allocator_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. Memory allocated with this function //!must be deallocated only with deallocate_one(). - multiallocation_chain allocate_individual(size_type num_elements) - { return multiallocation_chain(this->m_cache.cached_allocation(num_elements)); } + void allocate_individual(size_type num_elements, multiallocation_chain &chain) + { this->m_cache.cached_allocation(num_elements, chain); } //!Deallocates memory previously allocated with allocate_one(). //!You should never use deallocate_one to deallocate memory allocated @@ -655,12 +661,8 @@ class cached_allocator_impl //!preferred_elements. The number of actually allocated elements is //!will be assigned to received_size. Memory allocated with this function //!must be deallocated only with deallocate_one(). - void deallocate_individual(multiallocation_chain chain) - { - typename node_pool_t::multiallocation_chain mem - (chain.extract_multiallocation_chain()); - m_cache.cached_deallocation(boost::move(mem)); - } + void deallocate_individual(multiallocation_chain &chain) + { m_cache.cached_deallocation(chain); } //!Deallocates all free blocks of the pool void deallocate_free_blocks() @@ -678,9 +680,10 @@ class cached_allocator_impl void deallocate_free_chunks() { m_cache.get_node_pool()->deallocate_free_blocks(); } - /// @cond + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) private: cache_impl<node_pool_t> m_cache; + #endif //!defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) }; //!Equality test for same type of @@ -699,7 +702,7 @@ bool operator!=(const cached_allocator_impl<T, N, V> &alloc1, //!Pooled shared memory allocator using adaptive pool. Includes -//!a reference count but the class does not delete itself, this is +//!a reference count but the class does not delete itself, this is //!responsibility of user classes. Node size (NodeSize) and the number of //!nodes allocated per block (NodesPerBlock) are known at compile time template<class private_node_allocator_t> @@ -736,7 +739,7 @@ class shared_pool_impl //----------------------- return private_node_allocator_t::allocate_node(); } - + //!Deallocates an array pointed by ptr. Never throws void deallocate_node(void *ptr) { @@ -745,25 +748,15 @@ class shared_pool_impl //----------------------- private_node_allocator_t::deallocate_node(ptr); } -/* - //!Allocates a singly linked list of n nodes ending in null pointer. - //!can throw boost::interprocess::bad_alloc - void allocate_nodes(multiallocation_chain &nodes, size_type n) - { - //----------------------- - boost::interprocess::scoped_lock<mutex_type> guard(m_header); - //----------------------- - return private_node_allocator_t::allocate_nodes(nodes, n); - } -*/ + //!Allocates n nodes. //!Can throw boost::interprocess::bad_alloc - multiallocation_chain allocate_nodes(const size_type n) + void allocate_nodes(const size_type n, multiallocation_chain &chain) { //----------------------- boost::interprocess::scoped_lock<mutex_type> guard(m_header); //----------------------- - return private_node_allocator_t::allocate_nodes(n); + private_node_allocator_t::allocate_nodes(n, chain); } //!Deallocates a linked list of nodes ending in null pointer. Never throws @@ -776,12 +769,12 @@ class shared_pool_impl } //!Deallocates the nodes pointed by the multiallocation iterator. Never throws - void deallocate_nodes(multiallocation_chain chain) + void deallocate_nodes(multiallocation_chain &chain) { //----------------------- boost::interprocess::scoped_lock<mutex_type> guard(m_header); //----------------------- - private_node_allocator_t::deallocate_nodes(boost::move(chain)); + private_node_allocator_t::deallocate_nodes(chain); } //!Deallocates all the free blocks of memory. Never throws |