File indexing completed on 2025-09-15 08:38:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_ADAPTIVE_POOL_HPP
0012 #define BOOST_INTERPROCESS_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/detail/utilities.hpp>
0031 #include <boost/interprocess/detail/type_traits.hpp>
0032 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
0033 #include <boost/interprocess/containers/version_type.hpp>
0034 #include <boost/interprocess/exceptions.hpp>
0035 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
0036 #include <boost/container/detail/multiallocation_chain.hpp>
0037 #include <boost/interprocess/detail/mpl.hpp>
0038 #include <boost/move/adl_move_swap.hpp>
0039 #include <cstddef>
0040
0041
0042
0043
0044 namespace boost {
0045 namespace interprocess {
0046
0047 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0048
0049 namespace ipcdetail{
0050
0051 template < unsigned int Version
0052 , class T
0053 , class SegmentManager
0054 , std::size_t NodesPerBlock
0055 , std::size_t MaxFreeBlocks
0056 , unsigned char OverheadPercent
0057 >
0058 class adaptive_pool_base
0059 : public node_pool_allocation_impl
0060 < adaptive_pool_base
0061 < Version, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
0062 , Version
0063 , T
0064 , SegmentManager
0065 >
0066 {
0067 public:
0068 typedef typename SegmentManager::void_pointer void_pointer;
0069 typedef SegmentManager segment_manager;
0070 typedef adaptive_pool_base
0071 <Version, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> self_t;
0072
0073 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0074
0075 template <int dummy>
0076 struct node_pool
0077 {
0078 typedef ipcdetail::shared_adaptive_node_pool
0079 < SegmentManager, sizeof_value<T>::value, NodesPerBlock, MaxFreeBlocks, OverheadPercent> type;
0080
0081 static type *get(void *p)
0082 { return static_cast<type*>(p); }
0083 };
0084 #endif
0085
0086 BOOST_INTERPROCESS_STATIC_ASSERT((Version <=2));
0087
0088 public:
0089
0090 typedef typename boost::intrusive::
0091 pointer_traits<void_pointer>::template
0092 rebind_pointer<T>::type pointer;
0093 typedef typename boost::intrusive::
0094 pointer_traits<void_pointer>::template
0095 rebind_pointer<const T>::type const_pointer;
0096 typedef T value_type;
0097 typedef typename ipcdetail::add_reference
0098 <value_type>::type reference;
0099 typedef typename ipcdetail::add_reference
0100 <const value_type>::type const_reference;
0101 typedef typename segment_manager::size_type size_type;
0102 typedef typename segment_manager::difference_type difference_type;
0103
0104 typedef boost::interprocess::version_type<adaptive_pool_base, Version> version;
0105 typedef boost::container::dtl::transform_multiallocation_chain
0106 <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
0107
0108
0109
0110 template<class T2>
0111 struct rebind
0112 {
0113 typedef adaptive_pool_base<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0114 };
0115
0116 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0117 private:
0118
0119 template<unsigned int Version2, class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char O2>
0120 adaptive_pool_base& operator=
0121 (const adaptive_pool_base<Version2, T2, SegmentManager2, N2, F2, O2>&);
0122
0123 #endif
0124
0125 public:
0126
0127
0128
0129 adaptive_pool_base(segment_manager *segment_mngr)
0130 : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
0131
0132
0133
0134 adaptive_pool_base(const adaptive_pool_base &other)
0135 : mp_node_pool(other.get_node_pool())
0136 {
0137 node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
0138 }
0139
0140
0141 adaptive_pool_base& operator=(const adaptive_pool_base &other)
0142 {
0143 adaptive_pool_base c(other);
0144 boost::adl_move_swap(*this, c);
0145 return *this;
0146 }
0147
0148
0149
0150
0151 template<class T2>
0152 adaptive_pool_base
0153 (const adaptive_pool_base<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
0154 : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
0155
0156
0157
0158 ~adaptive_pool_base()
0159 { ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))); }
0160
0161
0162
0163 void* get_node_pool() const
0164 { return ipcdetail::to_raw_pointer(mp_node_pool); }
0165
0166
0167
0168 segment_manager* get_segment_manager()const
0169 { return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); }
0170
0171
0172
0173 friend void swap(self_t &alloc1, self_t &alloc2)
0174 { boost::adl_move_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
0175
0176 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0177 private:
0178 void_pointer mp_node_pool;
0179 #endif
0180 };
0181
0182
0183
0184 template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
0185 bool operator==(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
0186 const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
0187 { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
0188
0189
0190
0191 template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
0192 bool operator!=(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
0193 const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
0194 { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
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 adaptive_pool_v1
0203 : public adaptive_pool_base
0204 < 1
0205 , T
0206 , SegmentManager
0207 , NodesPerBlock
0208 , MaxFreeBlocks
0209 , OverheadPercent
0210 >
0211 {
0212 public:
0213 typedef ipcdetail::adaptive_pool_base
0214 < 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
0215
0216 template<class T2>
0217 struct rebind
0218 {
0219 typedef adaptive_pool_v1<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0220 };
0221
0222 adaptive_pool_v1(SegmentManager *segment_mngr)
0223 : base_t(segment_mngr)
0224 {}
0225
0226 template<class T2>
0227 adaptive_pool_v1
0228 (const 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
0251 template < class T
0252 , class SegmentManager
0253 , std::size_t NodesPerBlock
0254 , std::size_t MaxFreeBlocks
0255 , unsigned char OverheadPercent
0256 >
0257 class adaptive_pool
0258 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0259 : public ipcdetail::adaptive_pool_base
0260 < 2
0261 , T
0262 , SegmentManager
0263 , NodesPerBlock
0264 , MaxFreeBlocks
0265 , OverheadPercent
0266 >
0267 #endif
0268 {
0269
0270 #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0271 typedef ipcdetail::adaptive_pool_base
0272 < 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
0273 public:
0274 typedef boost::interprocess::version_type<adaptive_pool, 2> version;
0275
0276 template<class T2>
0277 struct rebind
0278 {
0279 typedef adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
0280 };
0281
0282 adaptive_pool(SegmentManager *segment_mngr)
0283 : base_t(segment_mngr)
0284 {}
0285
0286 template<class T2>
0287 adaptive_pool
0288 (const 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 adaptive_pool<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 adaptive_pool& operator=
0319 (const adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
0320
0321
0322
0323
0324
0325 public:
0326
0327
0328
0329 adaptive_pool(segment_manager *segment_mngr);
0330
0331
0332
0333 adaptive_pool(const adaptive_pool &other);
0334
0335
0336
0337
0338 template<class T2>
0339 adaptive_pool
0340 (const adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other);
0341
0342
0343
0344 ~adaptive_pool();
0345
0346
0347
0348 void* 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
0385
0386
0387
0388
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 adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
0453 const 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 adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
0459 const 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