File indexing completed on 2025-09-18 08:46:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_PRIVATE_ADAPTIVE_POOL_HPP
0012 #define BOOST_INTERPROCESS_PRIVATE_ADAPTIVE_POOL_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/adaptive_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
0040
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 , std::size_t MaxFreeBlocks
0054 , unsigned char OverheadPercent
0055 >
0056 class private_adaptive_pool_base
0057 : public node_pool_allocation_impl
0058 < private_adaptive_pool_base < Version, T, SegmentManager, NodesPerBlock
0059 , MaxFreeBlocks, OverheadPercent>
0060 , Version
0061 , T
0062 , SegmentManager
0063 >
0064 {
0065 public:
0066
0067 typedef SegmentManager segment_manager;
0068 typedef typename SegmentManager::void_pointer void_pointer;
0069
0070 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0071 private:
0072 typedef private_adaptive_pool_base
0073 < Version, T, SegmentManager, NodesPerBlock
0074 , MaxFreeBlocks, OverheadPercent> self_t;
0075 typedef ipcdetail::private_adaptive_node_pool
0076 <SegmentManager
0077 , sizeof_value<T>::value
0078 , NodesPerBlock
0079 , MaxFreeBlocks
0080 , OverheadPercent
0081 > node_pool_t;
0082
0083 BOOST_INTERPROCESS_STATIC_ASSERT((Version <=2));
0084
0085 #endif
0086
0087 public:
0088 typedef typename boost::intrusive::
0089 pointer_traits<void_pointer>::template
0090 rebind_pointer<T>::type pointer;
0091 typedef typename boost::intrusive::
0092 pointer_traits<void_pointer>::template
0093 rebind_pointer<const T>::type const_pointer;
0094 typedef T value_type;
0095 typedef typename ipcdetail::add_reference
0096 <value_type>::type reference;
0097 typedef typename ipcdetail::add_reference
0098 <const value_type>::type const_reference;
0099 typedef typename segment_manager::size_type size_type;
0100 typedef typename segment_manager::difference_type difference_type;
0101 typedef boost::interprocess::version_type
0102 <private_adaptive_pool_base, Version> version;
0103 typedef boost::container::dtl::transform_multiallocation_chain
0104 <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
0105
0106
0107 template<class T2>
0108 struct rebind
0109 {
0110 typedef private_adaptive_pool_base
0111 <Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0112 };
0113
0114 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0115
0116 template <int dummy>
0117 struct node_pool
0118 {
0119 typedef ipcdetail::private_adaptive_node_pool
0120 <SegmentManager
0121 , sizeof_value<T>::value
0122 , NodesPerBlock
0123 , MaxFreeBlocks
0124 , OverheadPercent
0125 > type;
0126
0127 static type *get(void *p)
0128 { return static_cast<type*>(p); }
0129 };
0130
0131 private:
0132
0133 template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2, std::size_t F2, unsigned char OP2>
0134 private_adaptive_pool_base& operator=
0135 (const private_adaptive_pool_base<Version2, T2, MemoryAlgorithm2, N2, F2, OP2>&);
0136
0137
0138 private_adaptive_pool_base& operator=(const private_adaptive_pool_base&);
0139 #endif
0140
0141 public:
0142
0143 private_adaptive_pool_base(segment_manager *segment_mngr)
0144 : m_node_pool(segment_mngr)
0145 {}
0146
0147
0148 private_adaptive_pool_base(const private_adaptive_pool_base &other)
0149 : m_node_pool(other.get_segment_manager())
0150 {}
0151
0152
0153 template<class T2>
0154 private_adaptive_pool_base
0155 (const private_adaptive_pool_base
0156 <Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
0157 : m_node_pool(other.get_segment_manager())
0158 {}
0159
0160
0161 ~private_adaptive_pool_base()
0162 {}
0163
0164
0165 segment_manager* get_segment_manager()const
0166 { return m_node_pool.get_segment_manager(); }
0167
0168
0169 node_pool_t* get_node_pool() const
0170 { return const_cast<node_pool_t*>(&m_node_pool); }
0171
0172
0173
0174 friend void swap(self_t &alloc1,self_t &alloc2)
0175 { boost::adl_move_swap(alloc1.m_node_pool, alloc2.m_node_pool); }
0176
0177 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0178 private:
0179 node_pool_t m_node_pool;
0180 #endif
0181 };
0182
0183
0184 template<unsigned int V, class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0185 bool operator==(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
0186 const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc2)
0187 { return &alloc1 == &alloc2; }
0188
0189
0190 template<unsigned int V, class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0191 bool operator!=(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
0192 const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc2)
0193 { return &alloc1 != &alloc2; }
0194
0195 template < class T
0196 , class SegmentManager
0197 , std::size_t NodesPerBlock = 64
0198 , std::size_t MaxFreeBlocks = 2
0199 , unsigned char OverheadPercent = 5
0200 >
0201 class private_adaptive_pool_v1
0202 : public private_adaptive_pool_base
0203 < 1
0204 , T
0205 , SegmentManager
0206 , NodesPerBlock
0207 , MaxFreeBlocks
0208 , OverheadPercent
0209 >
0210 {
0211 public:
0212 typedef ipcdetail::private_adaptive_pool_base
0213 < 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
0214
0215 template<class T2>
0216 struct rebind
0217 {
0218 typedef private_adaptive_pool_v1<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0219 };
0220
0221 private_adaptive_pool_v1(SegmentManager *segment_mngr)
0222 : base_t(segment_mngr)
0223 {}
0224
0225 template<class T2>
0226 private_adaptive_pool_v1
0227 (const private_adaptive_pool_v1<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
0228 : base_t(other)
0229 {}
0230 };
0231
0232 }
0233
0234 #endif
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 template < class T
0250 , class SegmentManager
0251 , std::size_t NodesPerBlock
0252 , std::size_t MaxFreeBlocks
0253 , unsigned char OverheadPercent
0254 >
0255 class private_adaptive_pool
0256 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0257 : public ipcdetail::private_adaptive_pool_base
0258 < 2
0259 , T
0260 , SegmentManager
0261 , NodesPerBlock
0262 , MaxFreeBlocks
0263 , OverheadPercent
0264 >
0265 #endif
0266 {
0267
0268 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0269 typedef ipcdetail::private_adaptive_pool_base
0270 < 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
0271 public:
0272 typedef boost::interprocess::version_type<private_adaptive_pool, 2> version;
0273
0274 template<class T2>
0275 struct rebind
0276 {
0277 typedef private_adaptive_pool
0278 <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0279 };
0280
0281 private_adaptive_pool(SegmentManager *segment_mngr)
0282 : base_t(segment_mngr)
0283 {}
0284
0285 template<class T2>
0286 private_adaptive_pool
0287 (const private_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
0288 : base_t(other)
0289 {}
0290
0291 #else
0292 public:
0293 typedef implementation_defined::segment_manager segment_manager;
0294 typedef segment_manager::void_pointer void_pointer;
0295 typedef implementation_defined::pointer pointer;
0296 typedef implementation_defined::const_pointer const_pointer;
0297 typedef T value_type;
0298 typedef typename ipcdetail::add_reference
0299 <value_type>::type reference;
0300 typedef typename ipcdetail::add_reference
0301 <const value_type>::type const_reference;
0302 typedef typename segment_manager::size_type size_type;
0303 typedef typename segment_manager::difference_type difference_type;
0304
0305
0306
0307 template<class T2>
0308 struct rebind
0309 {
0310 typedef private_adaptive_pool
0311 <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0312 };
0313
0314 private:
0315
0316
0317 template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
0318 private_adaptive_pool& operator=
0319 (const private_adaptive_pool<T2, SegmentManager2, N2, F2>&);
0320
0321
0322
0323 private_adaptive_pool& operator=(const private_adaptive_pool&);
0324
0325 public:
0326
0327
0328
0329 private_adaptive_pool(segment_manager *segment_mngr);
0330
0331
0332
0333 private_adaptive_pool(const private_adaptive_pool &other);
0334
0335
0336
0337
0338 template<class T2>
0339 private_adaptive_pool
0340 (const private_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other);
0341
0342
0343
0344 ~private_adaptive_pool();
0345
0346
0347
0348 node_pool_t* get_node_pool() const;
0349
0350
0351
0352 segment_manager* get_segment_manager()const;
0353
0354
0355
0356 size_type max_size() const;
0357
0358
0359
0360 pointer allocate(size_type count, cvoid_pointer hint = 0);
0361
0362
0363
0364 void deallocate(const pointer &ptr, size_type count);
0365
0366
0367
0368 void deallocate_free_blocks();
0369
0370
0371
0372 friend void swap(self_t &alloc1, self_t &alloc2);
0373
0374
0375
0376 pointer address(reference value) const;
0377
0378
0379
0380 const_pointer address(const_reference value) const;
0381
0382
0383
0384 void construct(const pointer &ptr, const_reference v);
0385
0386
0387
0388 void destroy(const pointer &ptr);
0389
0390
0391
0392
0393 size_type size(const pointer &p) const;
0394
0395 pointer allocation_command(boost::interprocess::allocation_type command,
0396 size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
0397
0398
0399
0400
0401
0402
0403
0404 void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain);
0405
0406
0407
0408
0409 void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain);
0410
0411
0412
0413
0414
0415
0416
0417 void deallocate_many(multiallocation_chain &chain);
0418
0419
0420
0421
0422 pointer allocate_one();
0423
0424
0425
0426
0427
0428
0429
0430 void allocate_individual(size_type num_elements, multiallocation_chain &chain);
0431
0432
0433
0434
0435 void deallocate_one(const pointer &p);
0436
0437
0438
0439
0440
0441
0442
0443 void deallocate_individual(multiallocation_chain &chain);
0444 #endif
0445 };
0446
0447 #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0448
0449
0450
0451 template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0452 bool operator==(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
0453 const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
0454
0455
0456
0457 template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
0458 bool operator!=(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
0459 const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
0460
0461 #endif
0462
0463 }
0464 }
0465
0466 #include <boost/interprocess/detail/config_end.hpp>
0467
0468 #endif
0469