PageRenderTime 44ms CodeModel.GetById 17ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/interprocess/allocators/cached_adaptive_pool.hpp

http://hadesmem.googlecode.com/
C++ Header | 354 lines | 182 code | 58 blank | 114 comment | 1 complexity | d4816ac15fa09dbbe0716af76003083c MD5 | raw file
  1//////////////////////////////////////////////////////////////////////////////
  2//
  3// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
  4// Software License, Version 1.0. (See accompanying file
  5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6//
  7// See http://www.boost.org/libs/interprocess for documentation.
  8//
  9//////////////////////////////////////////////////////////////////////////////
 10
 11#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP
 12#define BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP
 13
 14#if (defined _MSC_VER) && (_MSC_VER >= 1200)
 15#  pragma once
 16#endif
 17
 18#include <boost/interprocess/detail/config_begin.hpp>
 19#include <boost/interprocess/detail/workaround.hpp>
 20
 21#include <boost/interprocess/interprocess_fwd.hpp>
 22#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
 23#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 24#include <boost/interprocess/detail/utilities.hpp>
 25#include <boost/interprocess/detail/workaround.hpp>
 26#include <boost/interprocess/containers/version_type.hpp>
 27#include <boost/interprocess/allocators/detail/node_tools.hpp>
 28#include <cstddef>
 29
 30//!\file
 31//!Describes cached_adaptive_pool pooled shared memory STL compatible allocator 
 32
 33namespace boost {
 34namespace interprocess {
 35
 36/// @cond
 37
 38namespace detail {
 39
 40template < class T
 41         , class SegmentManager
 42         , std::size_t NodesPerBlock = 64
 43         , std::size_t MaxFreeBlocks = 2
 44         , unsigned char OverheadPercent = 5
 45         >
 46class cached_adaptive_pool_v1
 47   :  public detail::cached_allocator_impl
 48         < T
 49         , detail::shared_adaptive_node_pool
 50            < SegmentManager
 51            , sizeof_value<T>::value
 52            , NodesPerBlock
 53            , MaxFreeBlocks
 54            , OverheadPercent
 55            >
 56         , 1>
 57{
 58   public:
 59   typedef detail::cached_allocator_impl
 60         < T
 61         , detail::shared_adaptive_node_pool
 62            < SegmentManager
 63            , sizeof_value<T>::value
 64            , NodesPerBlock
 65            , MaxFreeBlocks
 66            , OverheadPercent
 67            >
 68         , 1> base_t;
 69
 70   template<class T2>
 71   struct rebind
 72   {  
 73      typedef cached_adaptive_pool_v1
 74         <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent>  other;
 75   };
 76
 77   cached_adaptive_pool_v1(SegmentManager *segment_mngr,
 78                         std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) 
 79      : base_t(segment_mngr, max_cached_nodes)
 80   {}
 81
 82   template<class T2>
 83   cached_adaptive_pool_v1
 84      (const cached_adaptive_pool_v1
 85         <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
 86      : base_t(other)
 87   {}
 88};
 89
 90}  //namespace detail{
 91
 92/// @endcond
 93
 94//!An STL node allocator that uses a segment manager as memory 
 95//!source. The internal pointer type will of the same type (raw, smart) as
 96//!"typename SegmentManager::void_pointer" type. This allows
 97//!placing the allocator in shared memory, memory mapped-files, etc...
 98//!
 99//!This node allocator shares a segregated storage between all instances of 
100//!cached_adaptive_pool with equal sizeof(T) placed in the same
101//!memory segment. But also caches some nodes privately to
102//!avoid some synchronization overhead.
103//!
104//!NodesPerBlock is the minimum number of nodes of nodes allocated at once when
105//!the allocator needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
106//!that the adaptive node pool will hold. The rest of the totally free blocks will be
107//!deallocated with the segment manager.
108//!
109//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
110//!(memory usable for nodes / total memory allocated from the segment manager)
111template < class T
112         , class SegmentManager
113         , std::size_t NodesPerBlock
114         , std::size_t MaxFreeBlocks
115         , unsigned char OverheadPercent
116         >
117class cached_adaptive_pool
118   /// @cond
119   :  public detail::cached_allocator_impl
120         < T
121         , detail::shared_adaptive_node_pool
122            < SegmentManager
123            , sizeof_value<T>::value
124            , NodesPerBlock
125            , MaxFreeBlocks
126            , OverheadPercent
127            >
128         , 2>
129   /// @endcond
130{
131
132   #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
133   public:
134   typedef detail::cached_allocator_impl
135         < T
136         , detail::shared_adaptive_node_pool
137            < SegmentManager
138            , sizeof_value<T>::value
139            , NodesPerBlock
140            , MaxFreeBlocks
141            , OverheadPercent
142            >
143         , 2> base_t;
144
145   public:
146   typedef boost::interprocess::version_type<cached_adaptive_pool, 2>   version;
147
148   template<class T2>
149   struct rebind
150   {  
151      typedef cached_adaptive_pool
152         <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent>  other;
153   };
154
155   cached_adaptive_pool(SegmentManager *segment_mngr,
156                         std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES) 
157      : base_t(segment_mngr, max_cached_nodes)
158   {}
159
160   template<class T2>
161   cached_adaptive_pool
162      (const cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
163      : base_t(other)
164   {}
165
166   #else
167   public:
168   typedef implementation_defined::segment_manager       segment_manager;
169   typedef segment_manager::void_pointer                 void_pointer;
170   typedef implementation_defined::pointer               pointer;
171   typedef implementation_defined::const_pointer         const_pointer;
172   typedef T                                             value_type;
173   typedef typename detail::add_reference
174                     <value_type>::type                  reference;
175   typedef typename detail::add_reference
176                     <const value_type>::type            const_reference;
177   typedef std::size_t                                   size_type;
178   typedef std::ptrdiff_t                                difference_type;
179
180   //!Obtains cached_adaptive_pool from 
181   //!cached_adaptive_pool
182   template<class T2>
183   struct rebind
184   {  
185      typedef cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
186   };
187
188   private:
189   //!Not assignable from
190   //!related cached_adaptive_pool
191   template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
192   cached_adaptive_pool& operator=
193      (const cached_adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
194
195   //!Not assignable from 
196   //!other cached_adaptive_pool
197   cached_adaptive_pool& operator=(const cached_adaptive_pool&);
198
199   public:
200   //!Constructor from a segment manager. If not present, constructs a node
201   //!pool. Increments the reference count of the associated node pool.
202   //!Can throw boost::interprocess::bad_alloc
203   cached_adaptive_pool(segment_manager *segment_mngr);
204
205   //!Copy constructor from other cached_adaptive_pool. Increments the reference 
206   //!count of the associated node pool. Never throws
207   cached_adaptive_pool(const cached_adaptive_pool &other);
208
209   //!Copy constructor from related cached_adaptive_pool. If not present, constructs
210   //!a node pool. Increments the reference count of the associated node pool.
211   //!Can throw boost::interprocess::bad_alloc
212   template<class T2>
213   cached_adaptive_pool
214      (const cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other);
215
216   //!Destructor, removes node_pool_t from memory
217   //!if its reference count reaches to zero. Never throws
218   ~cached_adaptive_pool();
219
220   //!Returns a pointer to the node pool.
221   //!Never throws
222   node_pool_t* get_node_pool() const;
223
224   //!Returns the segment manager.
225   //!Never throws
226   segment_manager* get_segment_manager()const;
227
228   //!Returns the number of elements that could be allocated.
229   //!Never throws
230   size_type max_size() const;
231
232   //!Allocate memory for an array of count elements. 
233   //!Throws boost::interprocess::bad_alloc if there is no enough memory
234   pointer allocate(size_type count, cvoid_pointer hint = 0);
235
236   //!Deallocate allocated memory.
237   //!Never throws
238   void deallocate(const pointer &ptr, size_type count);
239
240   //!Deallocates all free blocks
241   //!of the pool
242   void deallocate_free_blocks();
243
244   //!Swaps allocators. Does not throw. If each allocator is placed in a
245   //!different memory segment, the result is undefined.
246   friend void swap(self_t &alloc1, self_t &alloc2);
247
248   //!Returns address of mutable object.
249   //!Never throws
250   pointer address(reference value) const;
251
252   //!Returns address of non mutable object.
253   //!Never throws
254   const_pointer address(const_reference value) const;
255
256   //!Copy construct an object. 
257   //!Throws if T's copy constructor throws
258   void construct(const pointer &ptr, const_reference v);
259
260   //!Destroys object. Throws if object's
261   //!destructor throws
262   void destroy(const pointer &ptr);
263
264   //!Returns maximum the number of objects the previously allocated memory
265   //!pointed by p can hold. This size only works for memory allocated with
266   //!allocate, allocation_command and allocate_many.
267   size_type size(const pointer &p) const;
268
269   std::pair<pointer, bool>
270      allocation_command(boost::interprocess::allocation_type command,
271                         size_type limit_size, 
272                         size_type preferred_size,
273                         size_type &received_size, const pointer &reuse = 0);
274
275   //!Allocates many elements of size elem_size in a contiguous block
276   //!of memory. The minimum number to be allocated is min_elements,
277   //!the preferred and maximum number is
278   //!preferred_elements. The number of actually allocated elements is
279   //!will be assigned to received_size. The elements must be deallocated
280   //!with deallocate(...)
281   multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
282
283   //!Allocates n_elements elements, each one of size elem_sizes[i]in a
284   //!contiguous block
285   //!of memory. The elements must be deallocated
286   multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
287
288   //!Allocates many elements of size elem_size in a contiguous block
289   //!of memory. The minimum number to be allocated is min_elements,
290   //!the preferred and maximum number is
291   //!preferred_elements. The number of actually allocated elements is
292   //!will be assigned to received_size. The elements must be deallocated
293   //!with deallocate(...)
294   void deallocate_many(multiallocation_chain chain);
295
296   //!Allocates just one object. Memory allocated with this function
297   //!must be deallocated only with deallocate_one().
298   //!Throws boost::interprocess::bad_alloc if there is no enough memory
299   pointer allocate_one();
300
301   //!Allocates many elements of size == 1 in a contiguous block
302   //!of memory. The minimum number to be allocated is min_elements,
303   //!the preferred and maximum number is
304   //!preferred_elements. The number of actually allocated elements is
305   //!will be assigned to received_size. Memory allocated with this function
306   //!must be deallocated only with deallocate_one().
307   multiallocation_chain allocate_individual(std::size_t num_elements);
308
309   //!Deallocates memory previously allocated with allocate_one().
310   //!You should never use deallocate_one to deallocate memory allocated
311   //!with other functions different from allocate_one(). Never throws
312   void deallocate_one(const pointer &p);
313
314   //!Allocates many elements of size == 1 in a contiguous block
315   //!of memory. The minimum number to be allocated is min_elements,
316   //!the preferred and maximum number is
317   //!preferred_elements. The number of actually allocated elements is
318   //!will be assigned to received_size. Memory allocated with this function
319   //!must be deallocated only with deallocate_one().
320   void deallocate_individual(multiallocation_chain chain);
321   //!Sets the new max cached nodes value. This can provoke deallocations
322   //!if "newmax" is less than current cached nodes. Never throws
323   void set_max_cached_nodes(std::size_t newmax);
324
325   //!Returns the max cached nodes parameter.
326   //!Never throws
327   std::size_t get_max_cached_nodes() const;
328   #endif
329};
330
331#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
332
333//!Equality test for same type
334//!of cached_adaptive_pool
335template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
336bool operator==(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1, 
337                const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
338
339//!Inequality test for same type
340//!of cached_adaptive_pool
341template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
342bool operator!=(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1, 
343                const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
344
345#endif
346
347}  //namespace interprocess {
348}  //namespace boost {
349
350
351#include <boost/interprocess/detail/config_end.hpp>
352
353#endif   //#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP
354