Warning, file /include/oneapi/tbb/memory_pool.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_memory_pool_H
0018 #define __TBB_memory_pool_H
0019
0020 #if !TBB_PREVIEW_MEMORY_POOL
0021 #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h
0022 #endif
0023
0024
0025 #include "scalable_allocator.h"
0026
0027 #include <new> // std::bad_alloc
0028 #include <stdexcept> // std::runtime_error, std::invalid_argument
0029 #include <utility> // std::forward
0030
0031
0032 #if __TBB_EXTRA_DEBUG
0033 #define __TBBMALLOC_ASSERT ASSERT
0034 #else
0035 #define __TBBMALLOC_ASSERT(a,b) ((void)0)
0036 #endif
0037
0038 namespace tbb {
0039 namespace detail {
0040 namespace d1 {
0041
0042
0043 class pool_base : no_copy {
0044
0045
0046 public:
0047
0048 void recycle() { rml::pool_reset(my_pool); }
0049
0050
0051 void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); }
0052
0053
0054 void free(void* ptr) { rml::pool_free(my_pool, ptr); }
0055
0056
0057
0058 void *realloc(void* ptr, size_t size) {
0059 return rml::pool_realloc(my_pool, ptr, size);
0060 }
0061
0062 protected:
0063
0064 void destroy() { rml::pool_destroy(my_pool); }
0065
0066 rml::MemoryPool *my_pool;
0067 };
0068
0069 #if _MSC_VER && !defined(__INTEL_COMPILER)
0070
0071 #pragma warning (push)
0072 #pragma warning (disable: 4100)
0073 #endif
0074
0075
0076
0077 template<typename T, typename P = pool_base>
0078 class memory_pool_allocator {
0079 protected:
0080 typedef P pool_type;
0081 pool_type *my_pool;
0082 template<typename U, typename R>
0083 friend class memory_pool_allocator;
0084 template<typename V, typename U, typename R>
0085 friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
0086 template<typename V, typename U, typename R>
0087 friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
0088 public:
0089 typedef T value_type;
0090 typedef value_type* pointer;
0091 typedef const value_type* const_pointer;
0092 typedef value_type& reference;
0093 typedef const value_type& const_reference;
0094 typedef size_t size_type;
0095 typedef ptrdiff_t difference_type;
0096 template<typename U> struct rebind {
0097 typedef memory_pool_allocator<U, P> other;
0098 };
0099
0100 explicit memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {}
0101 memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
0102 template<typename U>
0103 memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
0104
0105 pointer address(reference x) const { return &x; }
0106 const_pointer address(const_reference x) const { return &x; }
0107
0108
0109 pointer allocate( size_type n, const void* = nullptr) {
0110 pointer p = static_cast<pointer>( my_pool->malloc( n*sizeof(value_type) ) );
0111 if (!p)
0112 throw_exception(std::bad_alloc());
0113 return p;
0114 }
0115
0116 void deallocate( pointer p, size_type ) {
0117 my_pool->free(p);
0118 }
0119
0120 size_type max_size() const throw() {
0121 size_type max = static_cast<size_type>(-1) / sizeof (value_type);
0122 return (max > 0 ? max : 1);
0123 }
0124
0125
0126 template<typename U, typename... Args>
0127 void construct(U *p, Args&&... args)
0128 { ::new((void *)p) U(std::forward<Args>(args)...); }
0129
0130
0131 void destroy( pointer p ) { p->~value_type(); }
0132
0133 };
0134
0135 #if _MSC_VER && !defined(__INTEL_COMPILER)
0136 #pragma warning (pop)
0137 #endif
0138
0139
0140
0141 template<typename P>
0142 class memory_pool_allocator<void, P> {
0143 public:
0144 typedef P pool_type;
0145 typedef void* pointer;
0146 typedef const void* const_pointer;
0147 typedef void value_type;
0148 template<typename U> struct rebind {
0149 typedef memory_pool_allocator<U, P> other;
0150 };
0151
0152 explicit memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {}
0153 memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
0154 template<typename U>
0155 memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
0156
0157 protected:
0158 pool_type *my_pool;
0159 template<typename U, typename R>
0160 friend class memory_pool_allocator;
0161 template<typename V, typename U, typename R>
0162 friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
0163 template<typename V, typename U, typename R>
0164 friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
0165 };
0166
0167 template<typename T, typename U, typename P>
0168 inline bool operator==( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool==b.my_pool;}
0169
0170 template<typename T, typename U, typename P>
0171 inline bool operator!=( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool!=b.my_pool;}
0172
0173
0174 template <typename Alloc>
0175 class memory_pool : public pool_base {
0176 Alloc my_alloc;
0177 static void *allocate_request(intptr_t pool_id, size_t & bytes);
0178 static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes);
0179
0180 public:
0181
0182 explicit memory_pool(const Alloc &src = Alloc());
0183
0184
0185 ~memory_pool() { destroy(); }
0186 };
0187
0188 class fixed_pool : public pool_base {
0189 void *my_buffer;
0190 size_t my_size;
0191 inline static void *allocate_request(intptr_t pool_id, size_t & bytes);
0192
0193 public:
0194
0195 inline fixed_pool(void *buf, size_t size);
0196
0197 ~fixed_pool() { destroy(); }
0198 };
0199
0200
0201
0202 template <typename Alloc>
0203 memory_pool<Alloc>::memory_pool(const Alloc &src) : my_alloc(src) {
0204 rml::MemPoolPolicy args(allocate_request, deallocate_request,
0205 sizeof(typename Alloc::value_type));
0206 rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
0207 if (res!=rml::POOL_OK)
0208 throw_exception(std::runtime_error("Can't create pool"));
0209 }
0210 template <typename Alloc>
0211 void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
0212 memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
0213 const size_t unit_size = sizeof(typename Alloc::value_type);
0214 __TBBMALLOC_ASSERT( 0 == bytes%unit_size, nullptr);
0215 void *ptr;
0216 #if TBB_USE_EXCEPTIONS
0217 try {
0218 #endif
0219 ptr = self.my_alloc.allocate( bytes/unit_size );
0220 #if TBB_USE_EXCEPTIONS
0221 } catch(...) {
0222 return nullptr;
0223 }
0224 #endif
0225 return ptr;
0226 }
0227 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
0228
0229
0230 #pragma warning (push)
0231 #pragma warning (disable: 4702)
0232 #endif
0233 template <typename Alloc>
0234 int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) {
0235 memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
0236 const size_t unit_size = sizeof(typename Alloc::value_type);
0237 __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, nullptr);
0238 self.my_alloc.deallocate( static_cast<typename Alloc::value_type*>(raw_ptr), raw_bytes/unit_size );
0239 return 0;
0240 }
0241 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
0242 #pragma warning (pop)
0243 #endif
0244 inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) {
0245 if (!buf || !size)
0246
0247 throw_exception(std::invalid_argument("Zero in parameter is invalid"));
0248 rml::MemPoolPolicy args(allocate_request, nullptr, size, true);
0249 rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
0250 if (res!=rml::POOL_OK)
0251 throw_exception(std::runtime_error("Can't create pool"));
0252 }
0253 inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) {
0254 fixed_pool &self = *reinterpret_cast<fixed_pool*>(pool_id);
0255 __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice.");
0256 bytes = self.my_size;
0257 self.my_size = 0;
0258 return self.my_buffer;
0259 }
0260
0261 }
0262 }
0263
0264 inline namespace v1 {
0265 using detail::d1::memory_pool_allocator;
0266 using detail::d1::memory_pool;
0267 using detail::d1::fixed_pool;
0268 }
0269 }
0270
0271 #undef __TBBMALLOC_ASSERT
0272 #endif