Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
memory_pool.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #ifndef __TBB_memory_pool_H
22 #define __TBB_memory_pool_H
23 
24 #if !TBB_PREVIEW_MEMORY_POOL
25 #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h
26 #endif
27 
29 #include "scalable_allocator.h"
30 #include <new> // std::bad_alloc
31 #include <stdexcept> // std::runtime_error, std::invalid_argument
32 // required in C++03 to construct std::runtime_error and std::invalid_argument
33 #include <string>
34 #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
35 #include <utility> // std::forward
36 #endif
37 
38 #if __TBB_EXTRA_DEBUG
39 #define __TBBMALLOC_ASSERT ASSERT
40 #else
41 #define __TBBMALLOC_ASSERT(a,b) ((void)0)
42 #endif
43 
44 namespace tbb {
45 namespace interface6 {
47 namespace internal {
48 
51  // Pool interface is separate from standard allocator classes because it has
52  // to maintain internal state, no copy or assignment. Move and swap are possible.
53 public:
55  void recycle() { rml::pool_reset(my_pool); }
56 
58  void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); }
59 
61  void free(void* ptr) { rml::pool_free(my_pool, ptr); }
62 
64  // Enables some low-level optimization possibilities
65  void *realloc(void* ptr, size_t size) {
66  return rml::pool_realloc(my_pool, ptr, size);
67  }
68 
69 protected:
71  void destroy() { rml::pool_destroy(my_pool); }
72 
73  rml::MemoryPool *my_pool;
74 };
75 
76 } // namespace internal
78 
79 #if _MSC_VER && !defined(__INTEL_COMPILER)
80  // Workaround for erroneous "unreferenced parameter" warning in method destroy.
81  #pragma warning (push)
82  #pragma warning (disable: 4100)
83 #endif
84 
86 
87 template<typename T, typename P = internal::pool_base>
89 protected:
90  typedef P pool_type;
92  template<typename U, typename R>
93  friend class memory_pool_allocator;
94  template<typename V, typename U, typename R>
95  friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
96  template<typename V, typename U, typename R>
97  friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
98 public:
100  typedef value_type* pointer;
101  typedef const value_type* const_pointer;
103  typedef const value_type& const_reference;
104  typedef size_t size_type;
105  typedef ptrdiff_t difference_type;
106  template<typename U> struct rebind {
108  };
109 
110  explicit memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {}
111  memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
112  template<typename U>
113  memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
114 
115  pointer address(reference x) const { return &x; }
116  const_pointer address(const_reference x) const { return &x; }
117 
119  pointer allocate( size_type n, const void* /*hint*/ = 0) {
120  pointer p = static_cast<pointer>( my_pool->malloc( n*sizeof(value_type) ) );
121  if (!p)
122  tbb::internal::throw_exception(std::bad_alloc());
123  return p;
124  }
127  my_pool->free(p);
128  }
130  size_type max_size() const throw() {
131  size_type max = static_cast<size_type>(-1) / sizeof (value_type);
132  return (max > 0 ? max : 1);
133  }
135 #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
136  template<typename U, typename... Args>
137  void construct(U *p, Args&&... args)
138  { ::new((void *)p) U(std::forward<Args>(args)...); }
139 #else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
140 #if __TBB_CPP11_RVALUE_REF_PRESENT
141  void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));}
142 #endif
143  void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); }
144 #endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
145 
147  void destroy( pointer p ) { p->~value_type(); }
148 
149 };
150 
151 #if _MSC_VER && !defined(__INTEL_COMPILER)
152  #pragma warning (pop)
153 #endif // warning 4100 is back
154 
156 
157 template<typename P>
159 public:
160  typedef P pool_type;
161  typedef void* pointer;
162  typedef const void* const_pointer;
163  typedef void value_type;
164  template<typename U> struct rebind {
166  };
167 
168  explicit memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {}
169  memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
170  template<typename U>
171  memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
172 
173 protected:
175  template<typename U, typename R>
176  friend class memory_pool_allocator;
177  template<typename V, typename U, typename R>
178  friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
179  template<typename V, typename U, typename R>
180  friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
181 };
182 
183 template<typename T, typename U, typename P>
184 inline bool operator==( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool==b.my_pool;}
185 
186 template<typename T, typename U, typename P>
187 inline bool operator!=( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool!=b.my_pool;}
188 
189 
191 template <typename Alloc>
192 class memory_pool : public internal::pool_base {
193  Alloc my_alloc; // TODO: base-class optimization
194  static void *allocate_request(intptr_t pool_id, size_t & bytes);
195  static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes);
196 
197 public:
199  explicit memory_pool(const Alloc &src = Alloc());
200 
202  ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter
203 
204 };
205 
206 class fixed_pool : public internal::pool_base {
207  void *my_buffer;
208  size_t my_size;
209  inline static void *allocate_request(intptr_t pool_id, size_t & bytes);
210 
211 public:
213  inline fixed_pool(void *buf, size_t size);
216 };
217 
219 
220 template <typename Alloc>
221 memory_pool<Alloc>::memory_pool(const Alloc &src) : my_alloc(src) {
222  rml::MemPoolPolicy args(allocate_request, deallocate_request,
223  sizeof(typename Alloc::value_type));
224  rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
225  if (res!=rml::POOL_OK)
226  tbb::internal::throw_exception(std::runtime_error("Can't create pool"));
227 }
228 template <typename Alloc>
229 void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
230  memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
231  const size_t unit_size = sizeof(typename Alloc::value_type);
232  __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL);
233  void *ptr;
234  __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); }
235  __TBB_CATCH(...) { return 0; }
236  return ptr;
237 }
238 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
239  // Workaround for erroneous "unreachable code" warning in the template below.
240  // Specific for VC++ 17-18 compiler
241  #pragma warning (push)
242  #pragma warning (disable: 4702)
243 #endif
244 template <typename Alloc>
245 int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) {
246  memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
247  const size_t unit_size = sizeof(typename Alloc::value_type);
248  __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL);
249  self.my_alloc.deallocate( static_cast<typename Alloc::value_type*>(raw_ptr), raw_bytes/unit_size );
250  return 0;
251 }
252 #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
253  #pragma warning (pop)
254 #endif
255 inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) {
256  if (!buf || !size)
257  // TODO: improve support for mode with exceptions disabled
258  tbb::internal::throw_exception(std::invalid_argument("Zero in parameter is invalid"));
259  rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true);
260  rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
261  if (res!=rml::POOL_OK)
262  tbb::internal::throw_exception(std::runtime_error("Can't create pool"));
263 }
264 inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) {
265  fixed_pool &self = *reinterpret_cast<fixed_pool*>(pool_id);
266  __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice.");
267  bytes = self.my_size;
268  self.my_size = 0; // remember that buffer has been used
269  return self.my_buffer;
270 }
271 
272 } //namespace interface6
276 } //namespace tbb
277 
278 #undef __TBBMALLOC_ASSERT
279 #endif// __TBB_memory_pool_H
friend bool operator==(const memory_pool_allocator< V, R > &a, const memory_pool_allocator< U, R > &b)
Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5.
Definition: memory_pool.h:88
const_pointer address(const_reference x) const
Definition: memory_pool.h:116
static void * allocate_request(intptr_t pool_id, size_t &bytes)
Definition: memory_pool.h:264
memory_pool_allocator(const memory_pool_allocator &src)
Definition: memory_pool.h:111
pointer address(reference x) const
Definition: memory_pool.h:115
Base of thread-safe pool allocator for variable-size requests.
Definition: memory_pool.h:50
fixed_pool(void *buf, size_t size)
construct pool with underlying allocator
Definition: memory_pool.h:255
void construct(pointer p, const value_type &value)
Definition: memory_pool.h:143
void * malloc(size_t size)
The "malloc" analogue to allocate block of memory of size bytes.
Definition: memory_pool.h:58
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:335
Thread-safe growable pool allocator for variable-size requests.
Definition: memory_pool.h:192
void deallocate(pointer p, size_type)
Free previously allocated block of memory.
Definition: memory_pool.h:126
static int deallocate_request(intptr_t pool_id, void *, size_t raw_bytes)
Definition: memory_pool.h:245
#define __TBB_TRY
Definition: tbb_stddef.h:287
friend bool operator!=(const memory_pool_allocator< V, R > &a, const memory_pool_allocator< U, R > &b)
memory_pool(const Alloc &src=Alloc())
construct pool with underlying allocator
Definition: memory_pool.h:221
memory_pool_allocator(const memory_pool_allocator &src)
Definition: memory_pool.h:169
void const char const char int ITT_FORMAT __itt_group_sync p
void throw_exception(exception_id eid)
Versionless convenience wrapper for throw_exception_v4()
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:116
void destroy(pointer p)
Destroy value at location pointed to by p.
Definition: memory_pool.h:147
bool operator!=(const memory_pool_allocator< T, P > &a, const memory_pool_allocator< U, P > &b)
Definition: memory_pool.h:187
#define __TBB_CATCH(e)
Definition: tbb_stddef.h:288
void * realloc(void *ptr, size_t size)
The "realloc" analogue complementing pool_malloc.
Definition: memory_pool.h:65
void construct(pointer p, value_type &&value)
Copy-construct value at location pointed to by p.
Definition: memory_pool.h:141
memory_pool_allocator< U, P > other
Definition: memory_pool.h:107
The graph class.
memory_pool_allocator(const memory_pool_allocator< U, P > &src)
Definition: memory_pool.h:171
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
size_type max_size() const
Largest value for which method allocate might succeed.
Definition: memory_pool.h:130
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:309
#define __TBBMALLOC_ASSERT(a, b)
Definition: memory_pool.h:41
void recycle()
Reset pool to reuse its memory (free all objects at once)
Definition: memory_pool.h:55
tbb::internal::allocator_type< T >::value_type value_type
Definition: memory_pool.h:99
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void free(void *ptr)
The "free" analogue to discard a previously allocated piece of memory.
Definition: memory_pool.h:61
pointer allocate(size_type n, const void *=0)
Allocate space for n objects.
Definition: memory_pool.h:119
memory_pool_allocator(const memory_pool_allocator< U, P > &src)
Definition: memory_pool.h:113
static void * allocate_request(intptr_t pool_id, size_t &bytes)
Definition: memory_pool.h:229
bool operator==(const memory_pool_allocator< T, P > &a, const memory_pool_allocator< U, P > &b)
Definition: memory_pool.h:184
void destroy()
destroy pool - must be called in a child class
Definition: memory_pool.h:71

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.