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