Update of /cvsroot/boost/boost/boost/interprocess/allocators
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv20029/allocators
Modified Files:
adaptive_pool.hpp allocation_type.hpp allocator.hpp
cached_adaptive_pool.hpp cached_node_allocator.hpp
Log Message:
New Interprocess version
Index: adaptive_pool.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/allocators/adaptive_pool.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- adaptive_pool.hpp 23 Jun 2007 12:51:56 -0000 1.4
+++ adaptive_pool.hpp 22 Jul 2007 14:02:16 -0000 1.5
@@ -20,6 +20,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
@@ -29,23 +30,21 @@
#include <stdio.h>
#include <cstddef>
-/*!\file
- Describes adaptive_pool pooled shared memory STL compatible allocator
-*/
+//!\file
+//!Describes adaptive_pool pooled shared memory STL compatible allocator
namespace boost {
-
namespace interprocess {
-/*!An STL node allocator that uses a segment manager as memory
- source. The internal pointer type will of the same type (raw, smart) as
- "typename SegmentManager::void_pointer" type. This allows
- placing the allocator in shared memory, memory mapped-files, etc...
- This node allocator shares a segregated storage between all instances
- of adaptive_pool with equal sizeof(T) placed in the same segment
- group. NodesPerChunk is the number of nodes allocated at once when the
allocator
- needs runs out of nodes. MaxFreeChunks is the number of free nodes
- in the adaptive node pool that will trigger the deallocation of*/
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!This node allocator shares a segregated storage between all instances
+//!of adaptive_pool with equal sizeof(T) placed in the same segment
+//!group. NodesPerChunk is the number of nodes allocated at once when the
allocator
+//!needs runs out of nodes. MaxFreeChunks is the number of free nodes
+//!in the adaptive node pool that will trigger the deallocation of
template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t
MaxFreeChunks>
class adaptive_pool
{
@@ -60,6 +59,11 @@
mutex_family::mutex_type mutex_type;
typedef adaptive_pool
<T, SegmentManager, NodesPerChunk, MaxFreeChunks> self_t;
+ typedef detail::shared_adaptive_node_pool
+ < SegmentManager, mutex_type
+ , sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
+ typedef typename detail::
+ pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
public:
//-------
@@ -75,7 +79,8 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- /*!Obtains adaptive_pool from other adaptive_pool*/
+ //!Obtains adaptive_pool from
+ //!adaptive_pool
template<class T2>
struct rebind
{
@@ -84,121 +89,115 @@
/// @cond
private:
- /*!Not assignable from related adaptive_pool*/
+ //!Not assignable from related adaptive_pool
template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2>
adaptive_pool& operator=
(const adaptive_pool<T2, SegmentManager2, N2, F2>&);
- /*!Not assignable from other adaptive_pool*/
+ //!Not assignable from other adaptive_pool
adaptive_pool& operator=(const adaptive_pool&);
/// @endcond
public:
- /*!Constructor from a segment manager. If not present, constructs a node
- pool. Increments the reference count of the associated node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
adaptive_pool(segment_manager *segment_mngr)
: mp_node_pool(priv_get_or_create(segment_mngr)) { }
- /*!Copy constructor from other adaptive_pool. Increments the reference
- count of the associated node pool. Never throws*/
+ //!Copy constructor from other adaptive_pool. Increments the reference
+ //!count of the associated node pool. Never throws
adaptive_pool(const adaptive_pool &other)
: mp_node_pool(other.get_node_pool())
{
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(other.get_node_pool());
- node_pool->inc_ref_count();
+ mp_node_pool->inc_ref_count();
}
- /*!Copy constructor from related adaptive_pool. If not present, constructs
- a node pool. Increments the reference count of the associated node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Copy constructor from related adaptive_pool. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
template<class T2>
adaptive_pool
(const adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks>
&other)
: mp_node_pool(priv_get_or_create(other.get_segment_manager())) { }
- /*!Destructor, removes node_pool_t from memory
- if its reference count reaches to zero. Never throws*/
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
~adaptive_pool()
{ priv_destroy_if_last_link(); }
- /*!Returns a pointer to the node pool. Never throws*/
- void* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const
+ { return detail::get_pointer(mp_node_pool); }
- /*!Returns the segment manager. Never throws*/
+ //!Returns the segment manager.
+ //!Never throws
segment_manager* get_segment_manager()const
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
- return node_pool->get_segment_manager();
- }
-/*
- //!Return address of mutable value. Never throws
- pointer address(reference value) const
- { return pointer(addressof(value)); }
-
- //!Return address of nonmutable value. Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
-
- //!Construct object, calling constructor.
- //!Throws if T(const Convertible &) throws
- template<class Convertible>
- void construct(const pointer &ptr, const Convertible &value)
- { new(detail::get_pointer(ptr)) value_type(value); }
+ { return mp_node_pool->get_segment_manager(); }
- //!Destroys object. Throws if object's destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-*/
- //!Returns the number of elements that could be allocated. Never throws
+ //!Returns the number of elements that could be allocated.
+ //!Never throws
size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
+ { return this->get_segment_manager()->get_size()/sizeof(value_type); }
- /*!Allocate memory for an array of count elements.
- Throws boost::interprocess::bad_alloc if there is no enough memory*/
+ //!Allocate memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory*/
pointer allocate(size_type count, cvoid_pointer = 0)
{
if(count > ((size_type)-1)/sizeof(value_type))
throw bad_alloc();
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
- return pointer(static_cast<T*>(node_pool->allocate(count)));
+ return pointer(static_cast<T*>(mp_node_pool->allocate(count)));
}
- /*!Deallocate allocated memory. Never throws*/
+ //!Deallocate allocated memory.
+ //!Never throws
void deallocate(const pointer &ptr, size_type count)
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
- node_pool->deallocate(detail::get_pointer(ptr), count);
- }
+ { mp_node_pool->deallocate(detail::get_pointer(ptr), count); }
- /*!Swaps allocators. Does not throw. If each allocator is placed in a
- different memory segment, the result is undefined.*/
+ //!Deallocates all free chunks of the pool
+ void deallocate_free_chunks()
+ { mp_node_pool->deallocate_free_chunks(); }
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+ //These functions are obsolete. These are here to conserve
+ //backwards compatibility with containers using them...
+
+ //!Returns address of mutable object.
+ //!Never throws
+ pointer address(reference value) const
+ { return pointer(boost::addressof(value)); }
+
+ //!Returns address of non mutable object.
+ //!Never throws
+ const_pointer address(const_reference value) const
+ { return const_pointer(boost::addressof(value)); }
+
+ //!Default construct an object.
+ //!Throws if T's default constructor throws*/
+ void construct(const pointer &ptr)
+ { new(detail::get_pointer(ptr)) value_type; }
+
+ //!Destroys object. Throws if object's
+ //!destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+
/// @cond
private:
- /*!Object function that creates the node allocator if it is not created and
- increments reference count if it is already created*/
+ //!Object function that creates the node allocator if it is not created and
+ //!increments reference count if it is already created
struct get_or_create_func
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- /*!This connects or constructs the unique instance of node_pool_t
- Can throw boost::interprocess::bad_alloc*/
+ //!This connects or constructs the unique instance of node_pool_t
+ //!Can throw boost::interprocess::bad_alloc
void operator()()
{
//Find or create the node_pool_t
@@ -209,32 +208,33 @@
mp_node_pool->inc_ref_count();
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function
+ //!object parameters
get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
node_pool_t *mp_node_pool;
segment_manager *mp_named_alloc;
};
- /*!Initialization function, creates an executes atomically the
- initialization object functions. Can throw
boost::interprocess::bad_alloc*/
- void *priv_get_or_create(segment_manager *named_alloc)
+ //!Initialization function, creates an executes atomically the
+ //!initialization object functions. Can throw boost::interprocess::bad_alloc
+ node_pool_t *priv_get_or_create(segment_manager *named_alloc)
{
get_or_create_func func(named_alloc);
named_alloc->atomic_func(func);
return func.mp_node_pool;
}
- /*!Object function that decrements the reference count. If the count
- reaches to zero destroys the node allocator from memory.
- Never throws*/
+ //!Object function that decrements the reference count. If the count
+ //!reaches to zero destroys the node allocator from memory.
+ //!Never throws
struct destroy_if_last_link_func
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- /*!Decrements reference count and destroys the object if there is no
- more attached allocators. Never throws*/
+ //!Decrements reference count and destroys the object if there is no
+ //!more attached allocators. Never throws
void operator()()
{
//If not the last link return
@@ -244,7 +244,8 @@
mp_named_alloc->template destroy<node_pool_t>(unique_instance);
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function
+ //!object parameters
destroy_if_last_link_func(segment_manager *nhdr,
node_pool_t *phdr)
: mp_named_alloc(nhdr), mp_node_pool(phdr){}
@@ -253,45 +254,33 @@
node_pool_t *mp_node_pool;
};
- /*!Destruction function, initializes and executes destruction function
- object. Never throws*/
+ //!Destruction function, initializes and executes destruction function
+ //!object. Never throws
void priv_destroy_if_last_link()
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
//Get segment manager
segment_manager *named_segment_mngr = this->get_segment_manager();
- //Get node pool pointer
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
-
//Execute destruction functor atomically
- destroy_if_last_link_func func(named_segment_mngr, node_pool);
+ destroy_if_last_link_func func(named_segment_mngr,
detail::get_pointer(mp_node_pool));
named_segment_mngr->atomic_func(func);
}
private:
- // We can't instantiate a pointer like this:
- // detail::shared_adaptive_node_pool<SegmentManager, mutex_type,
- // sizeof(T), NodesPerChunk, MaxFreeChunks>
*mp_node_pool;
- // since it can provoke an early instantiation of T, that could be
- // incomplete at that moment (for example, a node of a node-based container)
- // This provokes errors on some node based container implementations using
- // this pooled allocator as allocator type.
- //
- // Because of this, we will use a void offset pointer and we'll do some
- //(ugly )casts when needed.
- void_pointer mp_node_pool;
+ node_pool_ptr mp_node_pool;
/// @endcond
};
-/*!Equality test for same type of adaptive_pool*/
+//!Equality test for same type
+//!of adaptive_pool
template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
bool operator==(const adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
const adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
-/*!Inequality test for same type of adaptive_pool*/
+//!Inequality test for same type
+//!of adaptive_pool
template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
bool operator!=(const adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
const adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
Index: allocation_type.hpp
===================================================================
RCS file:
/cvsroot/boost/boost/boost/interprocess/allocators/allocation_type.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- allocation_type.hpp 12 May 2007 12:51:19 -0000 1.4
+++ allocation_type.hpp 22 Jul 2007 14:02:17 -0000 1.5
@@ -31,7 +31,8 @@
// expand_both = expand_fwd | expand_bwd,
// expand_or_new = allocate_new | expand_both,
shrink_in_place_v = 0x08,
- nothrow_allocation_v = 0x10
+ nothrow_allocation_v = 0x10,
+ zero_memory_v = 0x20
};
typedef int allocation_type;
@@ -41,6 +42,7 @@
static const allocation_type expand_bwd =
(allocation_type)expand_bwd_v;
static const allocation_type shrink_in_place =
(allocation_type)shrink_in_place_v;
static const allocation_type nothrow_allocation =
(allocation_type)nothrow_allocation_v;
+static const allocation_type zero_memory =
(allocation_type)zero_memory_v;
} //namespace interprocess {
} //namespace boost {
Index: allocator.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/allocators/allocator.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- allocator.hpp 23 Jun 2007 12:51:56 -0000 1.6
+++ allocator.hpp 22 Jul 2007 14:02:17 -0000 1.7
@@ -24,57 +24,66 @@
#include <boost/interprocess/detail/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/detail/iterators.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
-/*!\file
- Describes an allocator that allocates portions of fixed size
- memory buffer (shared memory, mapped file...)
-*/
+//!\file
+//!Describes an allocator that allocates portions of fixed size
+//!memory buffer (shared memory, mapped file...)
namespace boost {
-
namespace interprocess {
-/*!An STL compatible allocator that uses a segment manager as
- memory source. The internal pointer type will of the same type (raw, smart)
as
- "typename SegmentManager::void_pointer" type. This allows
- placing the allocator in shared memory, memory mapped-files, etc...*/
+
+//!An STL compatible allocator that uses a segment manager as
+//!memory source. The internal pointer type will of the same type (raw, smart)
as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
template<class T, class SegmentManager>
class allocator
{
/// @cond
private:
- /*!Self type*/
+
+ struct cast_functor
+ {
+ typedef typename detail::add_reference<T>::type result_type;
+ result_type operator()(char *ptr) const
+ { return *static_cast<T*>(static_cast<void*>(ptr)); }
+ };
+
+ //Self type
typedef allocator<T, SegmentManager> self_t;
- /*!Segment manager*/
+ //Segment manager
typedef SegmentManager segment_manager;
- /*!Pointer to void */
+ //Pointer to void
typedef typename segment_manager::void_pointer aux_pointer_t;
- /*!Typedef to const void pointer */
+ //Typedef to const void pointer
typedef typename
detail::pointer_to_other
<aux_pointer_t, const void>::type cvoid_ptr;
- /*!Pointer to the allocator*/
+ //Pointer to the allocator
typedef typename detail::pointer_to_other
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
- /*!Not assignable from related allocator*/
+ //Not assignable from related allocator
template<class T2, class SegmentManager2>
allocator& operator=(const allocator<T2, SegmentManager2>&);
- /*!Not assignable from other allocator*/
+ //Not assignable from other allocator
allocator& operator=(const allocator&);
- /*!Pointer to the allocator*/
+ //Pointer to the allocator
alloc_ptr_t mp_mngr;
/// @endcond
@@ -93,58 +102,67 @@
typedef detail::version_type<allocator, 2> version;
- /*!Obtains an allocator of other type*/
+ /// @cond
+
+ //Experimental. Don't use.
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , cast_functor> multiallocation_iterator;
+
+ /// @endcond
+
+ //!Obtains an allocator that allocates
+ //!objects of type T2
template<class T2>
struct rebind
{
typedef allocator<T2, SegmentManager> other;
};
- /*!Returns the segment manager. Never throws*/
+ //!Returns the segment manager.
+ //!Never throws
segment_manager* get_segment_manager()const
{ return detail::get_pointer(mp_mngr); }
-/*
- //!Returns address of mutable object. Never throws
- pointer address(reference value)
- { return pointer(addressof(value)); }
- //!Returns address of non mutable object. Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
-*/
- /*!Constructor from the segment manager. Never throws*/
+ //!Constructor from the segment manager.
+ //!Never throws
allocator(segment_manager *segment_mngr)
: mp_mngr(segment_mngr) { }
- /*!Constructor from other allocator. Never throws*/
+ //!Constructor from other allocator.
+ //!Never throws
allocator(const allocator &other)
: mp_mngr(other.get_segment_manager()){ }
- /*!Constructor from related allocator. Never throws*/
+ //!Constructor from related allocator.
+ //!Never throws
template<class T2>
allocator(const allocator<T2, SegmentManager> &other)
: mp_mngr(other.get_segment_manager()){}
- /*!Allocates memory for an array of count elements.
- Throws boost::interprocess::bad_alloc if there is no enough memory*/
+ //!Allocates memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_ptr hint = 0)
{
(void)hint;
- if(count > ((size_type)-1)/sizeof(value_type))
+ if(count > ((size_type)-1)/sizeof(T))
throw bad_alloc();
- return pointer((value_type*)mp_mngr->allocate(count*sizeof(value_type)));
+ return pointer((value_type*)mp_mngr->allocate(count*sizeof(T)));
}
- /*!Deallocates memory previously allocated. Never throws*/
+ //!Deallocates memory previously allocated.
+ //!Never throws
void deallocate(const pointer &ptr, size_type)
{ mp_mngr->deallocate(detail::get_pointer(ptr)); }
- /*!Returns the number of elements that could be allocated. Never throws*/
+ //!Returns the number of elements that could be allocated.
+ //!Never throws
size_type max_size() const
- { return mp_mngr->get_size()/sizeof(value_type); }
+ { return mp_mngr->get_size()/sizeof(T); }
- /*!Swap segment manager. Does not throw. If each allocator is placed in
- different memory segments, the result is undefined.*/
+ //!Swap segment manager. Does not throw. If each allocator is placed in
+ //!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
@@ -156,58 +174,106 @@
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
- std::pair<pointer, bool> ret;
- size_type max_count = ((size_type)-1)/sizeof(value_type);
- if(limit_size > max_count || preferred_size > max_count){
- if(command & nothrow_allocation){
- throw bad_alloc();
- }
- else{
- ret.first = 0;
- return ret;
- }
- }
-
- std::size_t l_size = limit_size*sizeof(value_type);
- std::size_t p_size = preferred_size*sizeof(value_type);
- std::size_t r_size;
- std::pair<void *, bool> result =
- mp_mngr->allocation_command
- (command, l_size, p_size, r_size, detail::get_pointer(reuse),
sizeof(value_type));
- received_size = r_size/sizeof(value_type);
- BOOST_ASSERT(0 == ((std::size_t)result.first %
detail::alignment_of<value_type>::value));
- return std::pair<pointer, bool>
- (static_cast<value_type*>(result.first), result.second);
+ return mp_mngr->allocation_command
+ (command, limit_size, preferred_size, received_size,
detail::get_pointer(reuse));
}
- /*!Returns maximum the number of objects the previously allocated memory
- pointed by p can hold.*/
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold.
size_type size(const pointer &p) const
{
- return (size_type)mp_mngr->size
- (detail::get_pointer(p))/sizeof(value_type);
+ return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
}
- /*!Allocates just one object. Memory allocated with this function
- must be deallocated only with deallocate_one().
- Throws boost::interprocess::bad_alloc if there is no enough memory*/
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate_one()
{ return this->allocate(1); }
- /*!Deallocates memory previously allocated with allocate_one().
- You should never use deallocate_one to deallocate memory allocated
- with other functions different from allocate_one(). Never throws*/
+ /// @cond
+
+ //Experimental. Don't use.
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!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_iterator allocate_individual(std::size_t min_elements,
std::size_t preferred_elements, std::size_t &received_elements)
+ {
+ return this->allocate_many
+ (1, min_elements, preferred_elements, received_elements);
+ }
+
+ /// @endcond
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &p)
{ return this->deallocate(p, 1); }
+
+ /// @cond
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t
min_elements, std::size_t preferred_elements, std::size_t &received_elements)
+ {
+ return multiallocation_iterator
+ (mp_mngr->allocate_many
+ (sizeof(T)*elem_size, min_elements, preferred_elements,
received_elements));
+ }
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes,
size_type n_elements)
+ {
+ return multiallocation_iterator
+ (mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
+ }
+
+ /// @endcond
+
+ //These functions are obsolete. These are here to conserve
+ //backwards compatibility with containers using them...
+
+ //!Returns address of mutable object.
+ //!Never throws
+ pointer address(reference value) const
+ { return pointer(boost::addressof(value)); }
+
+ //!Returns address of non mutable object.
+ //!Never throws
+ const_pointer address(const_reference value) const
+ { return const_pointer(boost::addressof(value)); }
+
+ //!Default construct an object.
+ //!Throws if T's default constructor throws*/
+ void construct(const pointer &ptr)
+ { new(detail::get_pointer(ptr)) value_type; }
+
+ //!Destroys object. Throws if object's
+ //!destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
};
-/*!Equality test for same type of allocator*/
+//!Equality test for same type
+//!of allocator
template<class T, class SegmentManager> inline
bool operator==(const allocator<T , SegmentManager> &alloc1,
const allocator<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
-/*!Inequality test for same type of allocator*/
+//!Inequality test for same type
+//!of allocator
template<class T, class SegmentManager> inline
bool operator!=(const allocator<T, SegmentManager> &alloc1,
const allocator<T, SegmentManager> &alloc2)
Index: cached_adaptive_pool.hpp
===================================================================
RCS file:
/cvsroot/boost/boost/boost/interprocess/allocators/cached_adaptive_pool.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cached_adaptive_pool.hpp 23 Jun 2007 12:51:56 -0000 1.4
+++ cached_adaptive_pool.hpp 22 Jul 2007 14:02:18 -0000 1.5
@@ -21,6 +21,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -30,21 +31,20 @@
#include <stdio.h>
#include <cstddef>
-/*!\file
- Describes cached_cached_node_allocator pooled shared memory STL compatible
allocator
-*/
+//!\file
+//!Describes cached_cached_node_allocator pooled shared memory STL compatible
allocator
namespace boost {
namespace interprocess {
-/*!An STL node allocator that uses a segment manager as memory
- source. The internal pointer type will of the same type (raw, smart) as
- "typename SegmentManager::void_pointer" type. This allows
- placing the allocator in shared memory, memory mapped-files, etc...
- This node allocator shares a segregated storage between all instances of
- cached_adaptive_pool with equal sizeof(T) placed in the same fixed size
- memory segment. But also caches some nodes privately to
- avoid some synchronization overhead.*/
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!This node allocator shares a segregated storage between all instances of
+//!cached_adaptive_pool with equal sizeof(T) placed in the same fixed size
+//!memory segment. But also caches some nodes privately to
+//!avoid some synchronization overhead.
template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t
MaxFreeChunks>
class cached_adaptive_pool
{
@@ -77,8 +77,14 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
+ typedef detail::shared_adaptive_node_pool
+ < SegmentManager, mutex_type
+ , sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
+ typedef typename detail::
+ pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
- /*!Obtains cached_adaptive_pool from other cached_adaptive_pool*/
+ //!Obtains cached_adaptive_pool from other
+ //!cached_adaptive_pool
template<class T2>
struct rebind
{
@@ -98,30 +104,25 @@
/// @endcond
public:
- /*!Constructor from a segment manager. If not present, constructs
- a node pool. Increments the reference count of the node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Constructor from a segment manager. If not present, constructs
+ //!a node pool. Increments the reference count of the node pool.
+ //!Can throw boost::interprocess::bad_alloc
cached_adaptive_pool(segment_manager *segment_mngr,
std::size_t max_cached_nodes =
DEFAULT_MAX_CACHED_NODES)
: mp_node_pool(priv_get_or_create(segment_mngr)),
m_max_cached_nodes(max_cached_nodes)
{}
- /*!Copy constructor from other cached_adaptive_pool. Increments the
- reference count of the associated node pool. Never throws*/
+ //!Copy constructor from other cached_adaptive_pool. Increments the
+ //!reference count of the associated node pool. Never throws
cached_adaptive_pool(const cached_adaptive_pool &other)
: mp_node_pool(other.get_node_pool()),
m_max_cached_nodes(other.get_max_cached_nodes())
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(other.get_node_pool());
- node_pool->inc_ref_count();
- }
+ { mp_node_pool->inc_ref_count(); }
- /*!Copy constructor from related cached_adaptive_pool. If not present,
constructs
- a node pool. Increments the reference count of the associated node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Copy constructor from related cached_adaptive_pool. If not present,
constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
template<class T2>
cached_adaptive_pool
(const cached_adaptive_pool<T2, SegmentManager, NodesPerChunk,
MaxFreeChunks> &other)
@@ -129,63 +130,44 @@
m_max_cached_nodes(other.get_max_cached_nodes())
{ }
- /*!Destructor, removes node_pool_t from memory
- if its reference count reaches to zero. Never throws*/
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
~cached_adaptive_pool()
{
priv_deallocate_all_cached_nodes();
priv_destroy_if_last_link();
}
- /*!Returns a pointer to the node pool. Never throws*/
- void* get_node_pool() const
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const
{ return detail::get_pointer(mp_node_pool); }
- /*!Returns the segment manager. Never throws*/
+ //!Returns the segment manager.
+ //!Never throws
segment_manager* get_segment_manager()const
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- return node_pool->get_segment_manager();
- }
+ { return mp_node_pool->get_segment_manager(); }
- /*!Sets the new max cached nodes value. This can provoke deallocations
- if "newmax" is less than current cached nodes. Never throws*/
+ //!Sets the new max cached nodes value. This can provoke deallocations
+ //!if "newmax" is less than current cached nodes. Never throws
void set_max_cached_nodes(std::size_t newmax)
{
m_max_cached_nodes = newmax;
priv_deallocate_remaining_nodes();
}
- /*!Returns the max cached nodes parameter. Never throws*/
+ //!Returns the max cached nodes parameter.
+ //!Never throws
std::size_t get_max_cached_nodes() const
{ return m_max_cached_nodes; }
-/*
- //!Return address of mutable value. Never throws
- pointer address(reference value)
- { return pointer(addressof(value)); }
- //!Return address of non mutable value. Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
-
- //!Construct object, calling constructor.
- //!Throws if T(const Convertible &) throws
- template<class Convertible>
- void construct(const pointer &ptr, const Convertible &value)
- { new(detail::get_pointer(ptr)) value_type(value); }
-
- //!Destroys object. Throws if object's destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-*/
- /*!Returns the number of elements that could be allocated. Never throws*/
+ //!Returns the number of elements that could be
+ //!allocated. Never throws
size_type max_size() const
{ return this->get_segment_manager()->get_size()/sizeof(value_type); }
- /*!Allocate memory for an array of count elements.
- Throws boost::interprocess::bad_alloc if there is no enough memory*/
+ //!Allocate memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
(void)hint;
@@ -199,15 +181,13 @@
if(count == 1){
//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()){
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
+ mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
}
ret = &m_cached_nodes.front();
m_cached_nodes.pop_front();
}
else{
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- ret = node_pool->allocate(count);
+ ret = mp_node_pool->allocate(count);
}
return pointer(static_cast<T*>(ret));
}
@@ -230,14 +210,16 @@
m_cached_nodes.push_front(*(node_t*)detail::char_ptr_cast(detail::get_pointer(ptr)));
}
else{
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
- node_pool->deallocate(detail::get_pointer(ptr), count);
+ mp_node_pool->deallocate(detail::get_pointer(ptr), count);
}
}
- /*!Swaps allocators. Does not throw. If each allocator is placed in a
- different shared memory segments, the result is undefined.*/
+ //!Deallocates all free chunks of the pool
+ void deallocate_free_chunks()
+ { mp_node_pool->deallocate_free_chunks(); }
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different shared memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{
detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool);
@@ -248,18 +230,41 @@
void deallocate_cache()
{ this->priv_deallocate_all_cached_nodes(); }
- /// @endcond
+ //These functions are obsolete. These are here to conserve
+ //backwards compatibility with containers using them...
+
+ //!Returns address of mutable object.
+ //!Never throws
+ pointer address(reference value) const
+ { return pointer(boost::addressof(value)); }
+
+ //!Returns address of non mutable object.
+ //!Never throws
+ const_pointer address(const_reference value) const
+ { return const_pointer(boost::addressof(value)); }
+
+ //!Default construct an object.
+ //!Throws if T's default constructor throws*/
+ void construct(const pointer &ptr)
+ { new(detail::get_pointer(ptr)) value_type; }
+
+ //!Destroys object. Throws if object's
+ //!destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+
+ /// @cond
private:
- /*!Object function that creates the node allocator if it is not created and
- increments reference count if it is already created*/
+ //!Object function that creates the node allocator if it is not created and
+ //!increments reference count if it is already created
struct get_or_create_func
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- /*!This connects or constructs the unique instance of node_pool_t
- Can throw boost::interprocess::bad_alloc*/
+ //!This connects or constructs the unique instance of node_pool_t
+ //!Can throw boost::interprocess::bad_alloc
void operator()()
{
//Find or create the node_pool_t
@@ -270,24 +275,24 @@
mp_node_pool->inc_ref_count();
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function
+ //!object parameters
get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
node_pool_t *mp_node_pool;
segment_manager *mp_named_alloc;
};
- /*!Frees all cached nodes. Never throws*/
+ //!Frees all cached nodes.
+ //!Never throws
void priv_deallocate_all_cached_nodes()
{
if(m_cached_nodes.empty()) return;
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- node_pool->deallocate_nodes(m_cached_nodes);
+ mp_node_pool->deallocate_nodes(m_cached_nodes);
}
- /*!Frees all cached nodes at once. Never throws*/
+ //!Frees all cached nodes at once.
+ //!Never throws
void priv_deallocate_remaining_nodes()
{
if(m_cached_nodes.size() > m_max_cached_nodes){
@@ -298,34 +303,29 @@
//!Frees n cached nodes at once. Never throws
void priv_deallocate_n_nodes(std::size_t n)
{
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
-
//Deallocate all new linked list at once
- node_pool->deallocate_nodes(m_cached_nodes, n);
+ mp_node_pool->deallocate_nodes(m_cached_nodes, n);
}
- /*!Initialization function, creates an executes atomically the
- initialization object functions. Can throw
boost::interprocess::bad_alloc*/
- void *priv_get_or_create(segment_manager *named_alloc)
+ //!Initialization function, creates an executes atomically the
+ //!initialization object functions. Can throw boost::interprocess::bad_alloc
+ node_pool_t *priv_get_or_create(segment_manager *named_alloc)
{
get_or_create_func func(named_alloc);
named_alloc->atomic_func(func);
return func.mp_node_pool;
}
- /*!Object function that decrements the reference count. If the count
- reaches to zero destroys the node allocator from memory.
- Never throws*/
+ //!Object function that decrements the reference count. If the count
+ //!reaches to zero destroys the node allocator from memory.
+ //!Never throws
struct destroy_if_last_link_func
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
- /*!Decrements reference count and destroys the object if there is no
- more attached allocators. Never throws*/
+ //!Decrements reference count and destroys the object if there is no
+ //!more attached allocators. Never throws
void operator()()
{
//If not the last link return
@@ -335,7 +335,8 @@
mp_named_alloc->template destroy<node_pool_t>(unique_instance);
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function
+ //!object parameters
destroy_if_last_link_func(segment_manager *nhdr,
node_pool_t *phdr)
: mp_named_alloc(nhdr), mp_node_pool(phdr){}
@@ -344,46 +345,35 @@
node_pool_t *mp_node_pool;
};
- /*!Destruction function, initializes and executes destruction function
- object. Never throws*/
+ //!Destruction function, initializes and executes destruction function
+ //!object. Never throws
void priv_destroy_if_last_link()
{
typedef detail::shared_adaptive_node_pool
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk,
MaxFreeChunks> node_pool_t;
//Get segment manager
segment_manager *segment_mngr = this->get_segment_manager();
- //Get pool pointer
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
//Execute destruction functor atomically
- destroy_if_last_link_func func(segment_mngr, node_pool);
+ destroy_if_last_link_func func(segment_mngr,
detail::get_pointer(mp_node_pool));
segment_mngr->atomic_func(func);
}
private:
- // We can't instantiate a pointer like this:
- // detail::shared_adaptive_node_pool<SegmentManager, mutex_type,
- // sizeof(T), NodesPerChunk, MaxFreeChunks>
*mp_node_pool;
- // since it can provoke an early instantiation of T, that could be
- // incomplete at that moment (for example, a node of a node-based container)
- // This provokes errors on some node based container implementations using
- // this pooled allocator as this allocator type.
- //
- // Because of this, we will use a void offset pointer and we'll do some
- //(ugly )casts when needed.
- void_pointer mp_node_pool;
+ node_pool_ptr mp_node_pool;
cached_list_t m_cached_nodes;
std::size_t m_max_cached_nodes;
/// @endcond
};
-/*!Equality test for same type of cached_adaptive_pool*/
+//!Equality test for same type of
+//!cached_adaptive_pool
template<class T, class S, std::size_t NodesPerChunk, std::size_t M> inline
bool operator==(const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc1,
const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
-/*!Inequality test for same type of cached_adaptive_pool*/
+//!Inequality test for same type of
+//!cached_adaptive_pool
template<class T, class S, std::size_t NodesPerChunk, std::size_t M> inline
bool operator!=(const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc1,
const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc2)
Index: cached_node_allocator.hpp
===================================================================
RCS file:
/cvsroot/boost/boost/boost/interprocess/allocators/cached_node_allocator.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cached_node_allocator.hpp 23 Jun 2007 12:51:56 -0000 1.6
+++ cached_node_allocator.hpp 22 Jul 2007 14:02:18 -0000 1.7
@@ -21,6 +21,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
#include <boost/interprocess/allocators/detail/node_pool.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -75,6 +76,11 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
+ typedef detail::shared_node_pool
+ < SegmentManager, mutex_type
+ , sizeof(T), NodesPerChunk> node_pool_t;
+ typedef typename detail::
+ pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
//!Obtains cached_node_allocator from other cached_node_allocator
template<class T2>
@@ -110,12 +116,7 @@
cached_node_allocator(const cached_node_allocator &other)
: mp_node_pool(other.get_node_pool()),
m_max_cached_nodes(other.get_max_cached_nodes())
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk>
node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(other.get_node_pool());
- node_pool->inc_ref_count();
- }
+ { mp_node_pool->inc_ref_count(); }
/*!Copy constructor from related cached_node_allocator. If not present,
constructs
a node pool. Increments the reference count of the associated node pool.
@@ -136,17 +137,12 @@
}
/*!Returns a pointer to the node pool. Never throws*/
- void* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ node_pool_t* get_node_pool() const
+ { return detail::get_pointer(mp_node_pool); }
/*!Returns the segment manager. Never throws*/
segment_manager* get_segment_manager()const
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk>
node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- return node_pool->get_segment_manager();
- }
+ { return mp_node_pool->get_segment_manager(); }
/*!Sets the new max cached nodes value. This can provoke deallocations
if "newmax" is less than current cached nodes. Never throws*/
@@ -159,25 +155,7 @@
/*!Returns the max cached nodes parameter. Never throws*/
std::size_t get_max_cached_nodes() const
{ return m_max_cached_nodes; }
-/*
- //!Return address of mutable value. Never throws
- pointer address(reference value) const
- { return pointer(addressof(value)); }
- //!Return address of non mutable value. Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
-
- //!Construct object, calling constructor.
- //!Throws if T(const Convertible &) throws
- template<class Convertible>
- void construct(const pointer &ptr, const Convertible &value)
- { new(detail::get_pointer(ptr)) value_type(value); }
-
- //!Destroys object. Throws if object's destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-*/
//!Returns the number of elements that could be allocated. Never throws
size_type max_size() const
{ return this->get_segment_manager()->get_size()/sizeof(value_type); }
@@ -197,15 +175,13 @@
if(count == 1){
//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()){
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
+ mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
}
ret = &m_cached_nodes.front();
m_cached_nodes.pop_front();
}
else{
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- ret = node_pool->allocate(count);
+ ret = mp_node_pool->allocate(count);
}
return pointer(static_cast<T*>(ret));
}
@@ -228,9 +204,7 @@
m_cached_nodes.push_front(*(node_t*)detail::char_ptr_cast(detail::get_pointer(ptr)));
}
else{
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
- node_pool->deallocate(detail::get_pointer(ptr), count);
+ mp_node_pool->deallocate(detail::get_pointer(ptr), count);
}
}
@@ -245,7 +219,33 @@
//!Returns the cached nodes to the shared pool
void deallocate_cache()
- { this->priv_deallocate_all_cached_nodes(); }
+ { this->priv_deallocate_all_cached_nodes(); }
+
+ //!Deallocates all free chunks of the pool
+ void deallocate_free_chunks()
+ { mp_node_pool->deallocate_free_chunks(); }
+
+ //These functions are obsolete. These are here to conserve
+ //backwards compatibility with containers using them...
+
+ //!Returns address of mutable object.
+ //!Never throws
+ pointer address(reference value) const
+ { return pointer(boost::addressof(value)); }
+
+ /*!Returns address of non mutable object. Never throws*/
+ const_pointer address(const_reference value) const
+ { return const_pointer(boost::addressof(value)); }
+
+ //!Default construct an object.
+ //!Throws if T's default constructor throws*/
+ void construct(const pointer &ptr)
+ { new(detail::get_pointer(ptr)) value_type; }
+
+ //!Destroys object. Throws if object's
+ //!destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
/// @cond
private:
@@ -273,17 +273,12 @@
get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
node_pool_t *mp_node_pool;
- segment_manager *mp_named_alloc;
+ segment_manager *mp_named_alloc;
};
/*!Frees all cached nodes. Never throws*/
void priv_deallocate_all_cached_nodes()
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk>
node_pool_t;
- node_pool_t *node_pool =
static_cast<node_pool_t*>(detail::get_pointer(mp_node_pool));
- node_pool->deallocate_nodes(m_cached_nodes);
- }
+ { mp_node_pool->deallocate_nodes(m_cached_nodes); }
/*!Frees all cached nodes at once. Never throws*/
void priv_deallocate_remaining_nodes()
@@ -295,19 +290,11 @@
/*!Frees n cached nodes at once. Never throws*/
void priv_deallocate_n_nodes(std::size_t n)
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
-
- //Deallocate all new linked list at once
- node_pool->deallocate_nodes(m_cached_nodes, n);
- }
+ { mp_node_pool->deallocate_nodes(m_cached_nodes, n); }
/*!Initialization function, creates an executes atomically the
initialization object functions. Can throw
boost::interprocess::bad_alloc*/
- void *priv_get_or_create(segment_manager *named_alloc)
+ node_pool_t *priv_get_or_create(segment_manager *named_alloc)
{
get_or_create_func func(named_alloc);
named_alloc->atomic_func(func);
@@ -350,26 +337,13 @@
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk>
node_pool_t;
//Get segment manager
segment_manager *segment_mngr = this->get_segment_manager();
- //Get pool pointer
- node_pool_t *node_pool = static_cast<node_pool_t*>
- (detail::get_pointer(mp_node_pool));
//Execute destruction functor atomically
- destroy_if_last_link_func func(segment_mngr, node_pool);
+ destroy_if_last_link_func func(segment_mngr,
detail::get_pointer(mp_node_pool));
segment_mngr->atomic_func(func);
}
private:
- // We can't instantiate a pointer like this:
- // detail::shared_node_pool<SegmentManager, mutex_type,
- // sizeof(T), NodesPerChunk> *mp_node_pool;
- // since it can provoke an early instantiation of T, that could be
- // incomplete at that moment (for example, a node of a node-based container)
- // This provokes errors on some node based container implementations using
- // this pooled allocator as this allocator type.
- //
- // Because of this, we will use a void offset pointer and we'll do some
- //(ugly )casts when needed.
- void_pointer mp_node_pool;
+ node_pool_ptr mp_node_pool;
cached_list_t m_cached_nodes;
std::size_t m_max_cached_nodes;
/// @endcond
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs