Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:53:23

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
0012 #define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 
0025 #include <boost/intrusive/pointer_traits.hpp>
0026 
0027 #include <boost/interprocess/interprocess_fwd.hpp>
0028 #include <boost/assert.hpp>
0029 #include <boost/container/detail/addressof.hpp>
0030 #include <boost/interprocess/allocators/detail/node_pool.hpp>
0031 #include <boost/interprocess/containers/version_type.hpp>
0032 #include <boost/container/detail/multiallocation_chain.hpp>
0033 #include <boost/interprocess/exceptions.hpp>
0034 #include <boost/interprocess/detail/utilities.hpp>
0035 #include <boost/interprocess/detail/workaround.hpp>
0036 #include <boost/move/adl_move_swap.hpp>
0037 #include <cstddef>
0038 
0039 //!\file
0040 //!Describes private_node_allocator_base pooled shared memory STL compatible allocator
0041 
0042 namespace boost {
0043 namespace interprocess {
0044 
0045 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0046 
0047 namespace ipcdetail {
0048 
0049 template < unsigned int Version
0050          , class T
0051          , class SegmentManager
0052          , std::size_t NodesPerBlock
0053          >
0054 class private_node_allocator_base
0055    : public node_pool_allocation_impl
0056    < private_node_allocator_base < Version, T, SegmentManager, NodesPerBlock>
0057    , Version
0058    , T
0059    , SegmentManager
0060    >
0061 {
0062    public:
0063    //Segment manager
0064    typedef SegmentManager                                segment_manager;
0065    typedef typename SegmentManager::void_pointer         void_pointer;
0066 
0067    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0068    private:
0069    typedef private_node_allocator_base
0070       < Version, T, SegmentManager, NodesPerBlock>       self_t;
0071    typedef ipcdetail::private_node_pool
0072       <SegmentManager
0073       , sizeof_value<T>::value
0074       , NodesPerBlock
0075       > node_pool_t;
0076 
0077    BOOST_INTERPROCESS_STATIC_ASSERT((Version <=2));
0078 
0079    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0080 
0081    public:
0082 
0083    typedef typename boost::intrusive::
0084       pointer_traits<void_pointer>::template
0085          rebind_pointer<T>::type                         pointer;
0086    typedef typename boost::intrusive::
0087       pointer_traits<void_pointer>::template
0088          rebind_pointer<const T>::type                   const_pointer;
0089    typedef T                                             value_type;
0090    typedef typename ipcdetail::add_reference
0091                      <value_type>::type                  reference;
0092    typedef typename ipcdetail::add_reference
0093                      <const value_type>::type            const_reference;
0094    typedef typename segment_manager::size_type           size_type;
0095    typedef typename segment_manager::difference_type     difference_type;
0096    typedef boost::interprocess::version_type
0097       <private_node_allocator_base, Version>              version;
0098    typedef boost::container::dtl::transform_multiallocation_chain
0099       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
0100 
0101    //!Obtains node_allocator from other node_allocator
0102    template<class T2>
0103    struct rebind
0104    {
0105       typedef private_node_allocator_base
0106          <Version, T2, SegmentManager, NodesPerBlock>   other;
0107    };
0108 
0109    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0110    template <int dummy>
0111    struct node_pool
0112    {
0113       typedef ipcdetail::private_node_pool
0114       <SegmentManager
0115       , sizeof_value<T>::value
0116       , NodesPerBlock
0117       > type;
0118 
0119       static type *get(void *p)
0120       {  return static_cast<type*>(p);  }
0121    };
0122 
0123    private:
0124    //!Not assignable from related private_node_allocator_base
0125    template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2>
0126    private_node_allocator_base& operator=
0127       (const private_node_allocator_base<Version2, T2, MemoryAlgorithm2, N2>&);
0128 
0129    //!Not assignable from other private_node_allocator_base
0130    private_node_allocator_base& operator=(const private_node_allocator_base&);
0131    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0132 
0133    public:
0134    //!Constructor from a segment manager
0135    private_node_allocator_base(segment_manager *segment_mngr)
0136       : m_node_pool(segment_mngr)
0137    {}
0138 
0139    //!Copy constructor from other private_node_allocator_base. Never throws
0140    private_node_allocator_base(const private_node_allocator_base &other)
0141       : m_node_pool(other.get_segment_manager())
0142    {}
0143 
0144    //!Copy constructor from related private_node_allocator_base. Never throws.
0145    template<class T2>
0146    private_node_allocator_base
0147       (const private_node_allocator_base
0148          <Version, T2, SegmentManager, NodesPerBlock> &other)
0149       : m_node_pool(other.get_segment_manager())
0150    {}
0151 
0152    //!Destructor, frees all used memory. Never throws
0153    ~private_node_allocator_base()
0154    {}
0155 
0156    //!Returns the segment manager. Never throws
0157    segment_manager* get_segment_manager()const
0158    {  return m_node_pool.get_segment_manager(); }
0159 
0160    //!Returns the internal node pool. Never throws
0161    node_pool_t* get_node_pool() const
0162    {  return const_cast<node_pool_t*>(&m_node_pool); }
0163 
0164    //!Swaps allocators. Does not throw. If each allocator is placed in a
0165    //!different shared memory segments, the result is undefined.
0166    friend void swap(self_t &alloc1,self_t &alloc2)
0167    {  boost::adl_move_swap(alloc1.m_node_pool, alloc2.m_node_pool);  }
0168 
0169    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0170    private:
0171    node_pool_t m_node_pool;
0172    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0173 };
0174 
0175 //!Equality test for same type of private_node_allocator_base
0176 template<unsigned int V, class T, class S, std::size_t NPC> inline
0177 bool operator==(const private_node_allocator_base<V, T, S, NPC> &alloc1,
0178                 const private_node_allocator_base<V, T, S, NPC> &alloc2)
0179 {  return &alloc1 == &alloc2; }
0180 
0181 //!Inequality test for same type of private_node_allocator_base
0182 template<unsigned int V, class T, class S, std::size_t NPC> inline
0183 bool operator!=(const private_node_allocator_base<V, T, S, NPC> &alloc1,
0184                 const private_node_allocator_base<V, T, S, NPC> &alloc2)
0185 {  return &alloc1 != &alloc2; }
0186 
0187 template < class T
0188          , class SegmentManager
0189          , std::size_t NodesPerBlock = 64
0190          >
0191 class private_node_allocator_v1
0192    :  public private_node_allocator_base
0193          < 1
0194          , T
0195          , SegmentManager
0196          , NodesPerBlock
0197          >
0198 {
0199    public:
0200    typedef ipcdetail::private_node_allocator_base
0201          < 1, T, SegmentManager, NodesPerBlock> base_t;
0202 
0203    template<class T2>
0204    struct rebind
0205    {
0206       typedef private_node_allocator_v1<T2, SegmentManager, NodesPerBlock>  other;
0207    };
0208 
0209    private_node_allocator_v1(SegmentManager *segment_mngr)
0210       : base_t(segment_mngr)
0211    {}
0212 
0213    template<class T2>
0214    private_node_allocator_v1
0215       (const private_node_allocator_v1<T2, SegmentManager, NodesPerBlock> &other)
0216       : base_t(other)
0217    {}
0218 };
0219 
0220 }  //namespace ipcdetail {
0221 
0222 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0223 
0224 //!An STL node allocator that uses a segment manager as memory
0225 //!source. The internal pointer type will of the same type (raw, smart) as
0226 //!"typename SegmentManager::void_pointer" type. This allows
0227 //!placing the allocator in shared memory, memory mapped-files, etc...
0228 //!This allocator has its own node pool. NodesPerBlock is the number of nodes allocated
0229 //!at once when the allocator needs runs out of nodes
0230 template < class T
0231          , class SegmentManager
0232          , std::size_t NodesPerBlock
0233          >
0234 class private_node_allocator
0235    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0236    :  public ipcdetail::private_node_allocator_base
0237          < 2
0238          , T
0239          , SegmentManager
0240          , NodesPerBlock
0241          >
0242    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0243 {
0244 
0245    #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0246    typedef ipcdetail::private_node_allocator_base
0247          < 2, T, SegmentManager, NodesPerBlock> base_t;
0248    public:
0249    typedef boost::interprocess::version_type<private_node_allocator, 2>   version;
0250 
0251    template<class T2>
0252    struct rebind
0253    {
0254       typedef private_node_allocator
0255          <T2, SegmentManager, NodesPerBlock>  other;
0256    };
0257 
0258    private_node_allocator(SegmentManager *segment_mngr)
0259       : base_t(segment_mngr)
0260    {}
0261 
0262    template<class T2>
0263    private_node_allocator
0264       (const private_node_allocator<T2, SegmentManager, NodesPerBlock> &other)
0265       : base_t(other)
0266    {}
0267 
0268    #else
0269    public:
0270    typedef implementation_defined::segment_manager       segment_manager;
0271    typedef segment_manager::void_pointer                 void_pointer;
0272    typedef implementation_defined::pointer               pointer;
0273    typedef implementation_defined::const_pointer         const_pointer;
0274    typedef T                                             value_type;
0275    typedef typename ipcdetail::add_reference
0276                      <value_type>::type                  reference;
0277    typedef typename ipcdetail::add_reference
0278                      <const value_type>::type            const_reference;
0279    typedef typename segment_manager::size_type           size_type;
0280    typedef typename segment_manage::difference_type      difference_type;
0281 
0282    //!Obtains private_node_allocator from
0283    //!private_node_allocator
0284    template<class T2>
0285    struct rebind
0286    {
0287       typedef private_node_allocator
0288          <T2, SegmentManager, NodesPerBlock> other;
0289    };
0290 
0291    private:
0292    //!Not assignable from
0293    //!related private_node_allocator
0294    template<class T2, class SegmentManager2, std::size_t N2>
0295    private_node_allocator& operator=
0296       (const private_node_allocator<T2, SegmentManager2, N2>&);
0297 
0298    //!Not assignable from
0299    //!other private_node_allocator
0300    private_node_allocator& operator=(const private_node_allocator&);
0301 
0302    public:
0303    //!Constructor from a segment manager. If not present, constructs a node
0304    //!pool. Increments the reference count of the associated node pool.
0305    //!Can throw boost::interprocess::bad_alloc
0306    private_node_allocator(segment_manager *segment_mngr);
0307 
0308    //!Copy constructor from other private_node_allocator. Increments the reference
0309    //!count of the associated node pool. Never throws
0310    private_node_allocator(const private_node_allocator &other);
0311 
0312    //!Copy constructor from related private_node_allocator. If not present, constructs
0313    //!a node pool. Increments the reference count of the associated node pool.
0314    //!Can throw boost::interprocess::bad_alloc
0315    template<class T2>
0316    private_node_allocator
0317       (const private_node_allocator<T2, SegmentManager, NodesPerBlock> &other);
0318 
0319    //!Destructor, removes node_pool_t from memory
0320    //!if its reference count reaches to zero. Never throws
0321    ~private_node_allocator();
0322 
0323    //!Returns a pointer to the node pool.
0324    //!Never throws
0325    node_pool_t* get_node_pool() const;
0326 
0327    //!Returns the segment manager.
0328    //!Never throws
0329    segment_manager* get_segment_manager()const;
0330 
0331    //!Returns the number of elements that could be allocated.
0332    //!Never throws
0333    size_type max_size() const;
0334 
0335    //!Allocate memory for an array of count elements.
0336    //!Throws boost::interprocess::bad_alloc if there is no enough memory
0337    pointer allocate(size_type count, cvoid_pointer hint = 0);
0338 
0339    //!Deallocate allocated memory.
0340    //!Never throws
0341    void deallocate(const pointer &ptr, size_type count);
0342 
0343    //!Deallocates all free blocks
0344    //!of the pool
0345    void deallocate_free_blocks();
0346 
0347    //!Swaps allocators. Does not throw. If each allocator is placed in a
0348    //!different memory segment, the result is undefined.
0349    friend void swap(self_t &alloc1, self_t &alloc2);
0350 
0351    //!Returns address of mutable object.
0352    //!Never throws
0353    pointer address(reference value) const;
0354 
0355    //!Returns address of non mutable object.
0356    //!Never throws
0357    const_pointer address(const_reference value) const;
0358 
0359    //!Copy construct an object.
0360    //!Throws if T's copy constructor throws
0361    void construct(const pointer &ptr, const_reference v);
0362 
0363    //!Destroys object. Throws if object's
0364    //!destructor throws
0365    void destroy(const pointer &ptr);
0366 
0367    //!Returns maximum the number of objects the previously allocated memory
0368    //!pointed by p can hold. This size only works for memory allocated with
0369    //!allocate, allocation_command and allocate_many.
0370    size_type size(const pointer &p) const;
0371 
0372    pointer allocation_command(boost::interprocess::allocation_type command,
0373                          size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
0374 
0375    //!Allocates many elements of size elem_size in a contiguous block
0376    //!of memory. The minimum number to be allocated is min_elements,
0377    //!the preferred and maximum number is
0378    //!preferred_elements. The number of actually allocated elements is
0379    //!will be assigned to received_size. The elements must be deallocated
0380    //!with deallocate(...)
0381    void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain);
0382 
0383    //!Allocates n_elements elements, each one of size elem_sizes[i]in a
0384    //!contiguous block
0385    //!of memory. The elements must be deallocated
0386    void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain);
0387 
0388    //!Allocates many elements of size elem_size in a contiguous block
0389    //!of memory. The minimum number to be allocated is min_elements,
0390    //!the preferred and maximum number is
0391    //!preferred_elements. The number of actually allocated elements is
0392    //!will be assigned to received_size. The elements must be deallocated
0393    //!with deallocate(...)
0394    void deallocate_many(multiallocation_chain &chain);
0395 
0396    //!Allocates just one object. Memory allocated with this function
0397    //!must be deallocated only with deallocate_one().
0398    //!Throws boost::interprocess::bad_alloc if there is no enough memory
0399    pointer allocate_one();
0400 
0401    //!Allocates many elements of size == 1 in a contiguous block
0402    //!of memory. The minimum number to be allocated is min_elements,
0403    //!the preferred and maximum number is
0404    //!preferred_elements. The number of actually allocated elements is
0405    //!will be assigned to received_size. Memory allocated with this function
0406    //!must be deallocated only with deallocate_one().
0407    void allocate_individual(size_type num_elements, multiallocation_chain &chain);
0408 
0409    //!Deallocates memory previously allocated with allocate_one().
0410    //!You should never use deallocate_one to deallocate memory allocated
0411    //!with other functions different from allocate_one(). Never throws
0412    void deallocate_one(const pointer &p);
0413 
0414    //!Allocates many elements of size == 1 in a contiguous block
0415    //!of memory. The minimum number to be allocated is min_elements,
0416    //!the preferred and maximum number is
0417    //!preferred_elements. The number of actually allocated elements is
0418    //!will be assigned to received_size. Memory allocated with this function
0419    //!must be deallocated only with deallocate_one().
0420    void deallocate_individual(multiallocation_chain &chain);
0421    #endif
0422 };
0423 
0424 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0425 
0426 //!Equality test for same type
0427 //!of private_node_allocator
0428 template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0429 bool operator==(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
0430                 const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc2);
0431 
0432 //!Inequality test for same type
0433 //!of private_node_allocator
0434 template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0435 bool operator!=(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
0436                 const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc2);
0437 
0438 #endif
0439 
0440 }  //namespace interprocess {
0441 }  //namespace boost {
0442 
0443 #include <boost/interprocess/detail/config_end.hpp>
0444 
0445 #endif   //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
0446