BRE12
scalable_allocator.h
Go to the documentation of this file.
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef __TBB_scalable_allocator_H
22 #define __TBB_scalable_allocator_H
23 
25 #include <stddef.h> /* Need ptrdiff_t and size_t from here. */
26 #if !_MSC_VER
27 #include <stdint.h> /* Need intptr_t from here. */
28 #endif
29 
30 #if !defined(__cplusplus) && __ICC==1100
31  #pragma warning (push)
32  #pragma warning (disable: 991)
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif /* __cplusplus */
38 
39 #if _MSC_VER >= 1400
40 #define __TBB_EXPORTED_FUNC __cdecl
41 #else
42 #define __TBB_EXPORTED_FUNC
43 #endif
44 
47 void * __TBB_EXPORTED_FUNC scalable_malloc (size_t size);
48 
51 void __TBB_EXPORTED_FUNC scalable_free (void* ptr);
52 
55 void * __TBB_EXPORTED_FUNC scalable_realloc (void* ptr, size_t size);
56 
59 void * __TBB_EXPORTED_FUNC scalable_calloc (size_t nobj, size_t size);
60 
63 int __TBB_EXPORTED_FUNC scalable_posix_memalign (void** memptr, size_t alignment, size_t size);
64 
67 void * __TBB_EXPORTED_FUNC scalable_aligned_malloc (size_t size, size_t alignment);
68 
71 void * __TBB_EXPORTED_FUNC scalable_aligned_realloc (void* ptr, size_t size, size_t alignment);
72 
75 void __TBB_EXPORTED_FUNC scalable_aligned_free (void* ptr);
76 
81 size_t __TBB_EXPORTED_FUNC scalable_msize (void* ptr);
82 
83 /* Results for scalable_allocation_* functions */
84 typedef enum {
85  TBBMALLOC_OK,
86  TBBMALLOC_INVALID_PARAM,
87  TBBMALLOC_UNSUPPORTED,
88  TBBMALLOC_NO_MEMORY,
89  TBBMALLOC_NO_EFFECT
90 } ScalableAllocationResult;
91 
92 /* Setting TBB_MALLOC_USE_HUGE_PAGES environment variable to 1 enables huge pages.
93  scalable_allocation_mode call has priority over environment variable. */
94 typedef enum {
95  TBBMALLOC_USE_HUGE_PAGES, /* value turns using huge pages on and off */
96  /* deprecated, kept for backward compatibility only */
97  USE_HUGE_PAGES = TBBMALLOC_USE_HUGE_PAGES,
98  /* try to limit memory consumption value Bytes, clean internal buffers
99  if limit is exceeded, but not prevents from requesting memory from OS */
100  TBBMALLOC_SET_SOFT_HEAP_LIMIT
101 } AllocationModeParam;
102 
105 int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value);
106 
107 typedef enum {
108  /* Clean internal allocator buffers for all threads.
109  Returns TBBMALLOC_NO_EFFECT if no buffers cleaned,
110  TBBMALLOC_OK if some memory released from buffers. */
111  TBBMALLOC_CLEAN_ALL_BUFFERS,
112  /* Clean internal allocator buffer for current thread only.
113  Return values same as for TBBMALLOC_CLEAN_ALL_BUFFERS. */
114  TBBMALLOC_CLEAN_THREAD_BUFFERS
115 } ScalableAllocationCmd;
116 
119 int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param);
120 
121 #ifdef __cplusplus
122 } /* extern "C" */
123 #endif /* __cplusplus */
124 
125 #ifdef __cplusplus
126 
128 namespace rml {
129 class MemoryPool;
130 
131 typedef void *(*rawAllocType)(intptr_t pool_id, size_t &bytes);
132 // returns non-zero in case of error
133 typedef int (*rawFreeType)(intptr_t pool_id, void* raw_ptr, size_t raw_bytes);
134 
135 /*
136 MemPoolPolicy extension must be compatible with such structure fields layout
137 
138 struct MemPoolPolicy {
139  rawAllocType pAlloc;
140  rawFreeType pFree;
141  size_t granularity; // granularity of pAlloc allocations
142 };
143 */
144 
145 struct MemPoolPolicy {
146  enum {
147  TBBMALLOC_POOL_VERSION = 1
148  };
149 
150  rawAllocType pAlloc;
151  rawFreeType pFree;
152  // granularity of pAlloc allocations. 0 means default used.
153  size_t granularity;
154  int version;
155  // all memory consumed at 1st pAlloc call and never returned,
156  // no more pAlloc calls after 1st
157  unsigned fixedPool : 1,
158  // memory consumed but returned only at pool termination
159  keepAllMemory : 1,
160  reserved : 30;
161 
162  MemPoolPolicy(rawAllocType pAlloc_, rawFreeType pFree_,
163  size_t granularity_ = 0, bool fixedPool_ = false,
164  bool keepAllMemory_ = false) :
165  pAlloc(pAlloc_), pFree(pFree_), granularity(granularity_), version(TBBMALLOC_POOL_VERSION),
166  fixedPool(fixedPool_), keepAllMemory(keepAllMemory_),
167  reserved(0) {}
168 };
169 
170 // enums have same values as appropriate enums from ScalableAllocationResult
171 // TODO: use ScalableAllocationResult in pool_create directly
172 enum MemPoolError {
173  // pool created successfully
174  POOL_OK = TBBMALLOC_OK,
175  // invalid policy parameters found
176  INVALID_POLICY = TBBMALLOC_INVALID_PARAM,
177  // requested pool policy is not supported by allocator library
178  UNSUPPORTED_POLICY = TBBMALLOC_UNSUPPORTED,
179  // lack of memory during pool creation
180  NO_MEMORY = TBBMALLOC_NO_MEMORY,
181  // action takes no effect
182  NO_EFFECT = TBBMALLOC_NO_EFFECT
183 };
184 
185 MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy,
186  rml::MemoryPool **pool);
187 
188 bool pool_destroy(MemoryPool* memPool);
189 void *pool_malloc(MemoryPool* memPool, size_t size);
190 void *pool_realloc(MemoryPool* memPool, void *object, size_t size);
191 void *pool_aligned_malloc(MemoryPool* mPool, size_t size, size_t alignment);
192 void *pool_aligned_realloc(MemoryPool* mPool, void *ptr, size_t size, size_t alignment);
193 bool pool_reset(MemoryPool* memPool);
194 bool pool_free(MemoryPool *memPool, void *object);
195 MemoryPool *pool_identify(void *object);
196 }
197 
198 #include <new> /* To use new with the placement argument */
199 
200 /* Ensure that including this header does not cause implicit linkage with TBB */
201 #ifndef __TBB_NO_IMPLICIT_LINKAGE
202  #define __TBB_NO_IMPLICIT_LINKAGE 1
203  #include "tbb_stddef.h"
204  #undef __TBB_NO_IMPLICIT_LINKAGE
205 #else
206  #include "tbb_stddef.h"
207 #endif
208 
209 #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
210  #include <utility> // std::forward
211 #endif
212 
213 namespace tbb {
214 
215 #if _MSC_VER && !defined(__INTEL_COMPILER)
216  // Workaround for erroneous "unreferenced parameter" warning in method destroy.
217  #pragma warning (push)
218  #pragma warning (disable: 4100)
219 #endif
220 
222 namespace internal {
223 
224 #if TBB_USE_EXCEPTIONS
225 // forward declaration is for inlining prevention
226 template<typename E> __TBB_NOINLINE( void throw_exception(const E &e) );
227 #endif
228 
229 // keep throw in a separate function to prevent code bloat
230 template<typename E>
231 void throw_exception(const E &e) {
232  __TBB_THROW(e);
233 }
234 
235 } // namespace internal
237 
239 
242 template<typename T>
243 class scalable_allocator {
244 public:
245  typedef typename internal::allocator_type<T>::value_type value_type;
246  typedef value_type* pointer;
247  typedef const value_type* const_pointer;
248  typedef value_type& reference;
249  typedef const value_type& const_reference;
250  typedef size_t size_type;
251  typedef ptrdiff_t difference_type;
252  template<class U> struct rebind {
253  typedef scalable_allocator<U> other;
254  };
255 
256  scalable_allocator() throw() {}
257  scalable_allocator( const scalable_allocator& ) throw() {}
258  template<typename U> scalable_allocator(const scalable_allocator<U>&) throw() {}
259 
260  pointer address(reference x) const {return &x;}
261  const_pointer address(const_reference x) const {return &x;}
262 
264  pointer allocate( size_type n, const void* /*hint*/ =0 ) {
265  pointer p = static_cast<pointer>( scalable_malloc( n * sizeof(value_type) ) );
266  if (!p)
267  internal::throw_exception(std::bad_alloc());
268  return p;
269  }
270 
272  void deallocate( pointer p, size_type ) {
273  scalable_free( p );
274  }
275 
277  size_type max_size() const throw() {
278  size_type absolutemax = static_cast<size_type>(-1) / sizeof (value_type);
279  return (absolutemax > 0 ? absolutemax : 1);
280  }
281 #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
282  template<typename U, typename... Args>
283  void construct(U *p, Args&&... args)
284  { ::new((void *)p) U(std::forward<Args>(args)...); }
285 #else /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */
286 #if __TBB_CPP11_RVALUE_REF_PRESENT
287  void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); }
288 #endif
289  void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
290 #endif /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */
291  void destroy( pointer p ) {p->~value_type();}
292 };
293 
294 #if _MSC_VER && !defined(__INTEL_COMPILER)
295  #pragma warning (pop)
296 #endif /* warning 4100 is back */
297 
299 
300 template<>
301 class scalable_allocator<void> {
302 public:
303  typedef void* pointer;
304  typedef const void* const_pointer;
305  typedef void value_type;
306  template<class U> struct rebind {
307  typedef scalable_allocator<U> other;
308  };
309 };
310 
311 template<typename T, typename U>
312 inline bool operator==( const scalable_allocator<T>&, const scalable_allocator<U>& ) {return true;}
313 
314 template<typename T, typename U>
315 inline bool operator!=( const scalable_allocator<T>&, const scalable_allocator<U>& ) {return false;}
316 
317 } // namespace tbb
318 
319 #if _MSC_VER
320  #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE)
321  #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1
322  #endif
323 
324  #if !__TBBMALLOC_NO_IMPLICIT_LINKAGE
325  #ifdef _DEBUG
326  #pragma comment(lib, "tbbmalloc_debug.lib")
327  #else
328  #pragma comment(lib, "tbbmalloc.lib")
329  #endif
330  #endif
331 
332 
333 #endif
334 
335 #endif /* __cplusplus */
336 
337 #if !defined(__cplusplus) && __ICC==1100
338  #pragma warning (pop)
339 #endif /* ICC 11.0 warning 991 is back */
340 
341 #endif /* __TBB_scalable_allocator_H */
int __TBB_EXPORTED_FUNC scalable_posix_memalign(void **memptr, size_t alignment, size_t size)
The "posix_memalign" analogue.
void *__TBB_EXPORTED_FUNC scalable_malloc(size_t size)
The "malloc" analogue to allocate block of memory of size bytes.
Definition: _tbb_windef.h:37
void *__TBB_EXPORTED_FUNC scalable_aligned_malloc(size_t size, size_t alignment)
The "_aligned_malloc" analogue.
void *__TBB_EXPORTED_FUNC scalable_realloc(void *ptr, size_t size)
The "realloc" analogue complementing scalable_malloc.
size_t __TBB_EXPORTED_FUNC scalable_msize(void *ptr)
The analogue of _msize/malloc_size/malloc_usable_size.
Definition: _flow_graph_async_msg_impl.h:32
void __TBB_EXPORTED_FUNC scalable_free(void *ptr)
The "free" analogue to discard a previously allocated piece of memory.
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
void *__TBB_EXPORTED_FUNC scalable_aligned_realloc(void *ptr, size_t size, size_t alignment)
The "_aligned_realloc" analogue.
int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param)
Call TBB allocator-specific commands.
void __TBB_EXPORTED_FUNC scalable_aligned_free(void *ptr)
The "_aligned_free" analogue.
int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value)
Set TBB allocator-specific allocation modes.
void *__TBB_EXPORTED_FUNC scalable_calloc(size_t nobj, size_t size)
The "calloc" analogue complementing scalable_malloc.