summaryrefslogtreecommitdiff
path: root/boost/interprocess/allocators/detail/allocator_common.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/allocators/detail/allocator_common.hpp')
-rw-r--r--boost/interprocess/allocators/detail/allocator_common.hpp121
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