- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# memory_pool.h

Go to the documentation of this file.

    00001 /*
    00002     Copyright 2005-2012 Intel Corporation.  All Rights Reserved.
    00003
    00004     This file is part of Threading Building Blocks.
    00005
    00006     Threading Building Blocks is free software; you can redistribute it
    00007     and/or modify it under the terms of the GNU General Public License
    00008     version 2 as published by the Free Software Foundation.
    00009
    00010     Threading Building Blocks is distributed in the hope that it will be
    00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00013     GNU General Public License for more details.
    00014
    00015     You should have received a copy of the GNU General Public License
    00016     along with Threading Building Blocks; if not, write to the Free Software
    00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    00018
    00019     As a special exception, you may use this file as part of a free software
    00020     library without restriction.  Specifically, if other files instantiate
    00021     templates or use macros or inline functions from this file, or you compile
    00022     this file and link it with other files to produce an executable, this
    00023     file does not by itself cause the resulting executable to be covered by
    00024     the GNU General Public License.  This exception does not however
    00025     invalidate any other reasons why the executable file might be covered by
    00026     the GNU General Public License.
    00027 */
    00028
    00029 #ifndef __TBB_memory_pool_H
    00030 #define __TBB_memory_pool_H
    00031
    00032 #if !TBB_PREVIEW_MEMORY_POOL
    00033 #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h
    00034 #endif
    00035
    00037 #include "scalable_allocator.h"
    00038 #include "tbb_stddef.h"
    00039 #include "tbb_machine.h" // TODO: avoid linkage with libtbb on IA-64
    00040 #include <new> // std::bad_alloc
    00041 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
    00042 #include <utility> // std::forward
    00043 #endif
    00044
    00045 #if __TBB_EXTRA_DEBUG
    00046 #define __TBBMALLOC_ASSERT ASSERT
    00047 #else
    00048 #define __TBBMALLOC_ASSERT(a,b) ((void)0)
    00049 #endif
    00050
    00051 namespace tbb {
    00052 namespace interface6 {
    00054 namespace internal {
    00055
    00057 class pool_base : tbb::internal::no_copy {
    00058     // Pool interface is separate from standard allocator classes because it has
    00059     // to maintain internal state, no copy or assignment. Move and swap are possible.
    00060 public:
    00062     void recycle() { rml::pool_reset(my_pool); }
    00063
    00065     void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); }
    00066
    00068     void free(void* ptr) { rml::pool_free(my_pool, ptr); }
    00069
    00071     // Enables some low-level optimization possibilities
    00072     void *realloc(void* ptr, size_t size) {
    00073         return rml::pool_realloc(my_pool, ptr, size);
    00074     }
    00075
    00076 protected:
    00078     void destroy() { rml::pool_destroy(my_pool); }
    00079
    00080     rml::MemoryPool *my_pool;
    00081 };
    00082
    00083 } // namespace internal
    00085
    00086 #if _MSC_VER && !defined(__INTEL_COMPILER)
    00087     // Workaround for erroneous "unreferenced parameter" warning in method destroy.
    00088     #pragma warning (push)
    00089     #pragma warning (disable: 4100)
    00090 #endif
    00091
    00093
    00094 template<typename T, typename P = internal::pool_base>
    00095 class memory_pool_allocator {
    00096 protected:
    00097     typedef P pool_type;
    00098     pool_type *my_pool;
    00099     template<typename U, typename R>
    00100     friend class memory_pool_allocator;
    00101     template<typename V, typename U, typename R>
    00102     friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00103     template<typename V, typename U, typename R>
    00104     friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00105 public:
    00106     typedef typename tbb::internal::allocator_type<T>::value_type value_type;
    00107     typedef value_type* pointer;
    00108     typedef const value_type* const_pointer;
    00109     typedef value_type& reference;
    00110     typedef const value_type& const_reference;
    00111     typedef size_t size_type;
    00112     typedef ptrdiff_t difference_type;
    00113     template<typename U> struct rebind {
    00114         typedef memory_pool_allocator<U, P> other;
    00115     };
    00116
    00117     memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {}
    00118     memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
    00119     template<typename U>
    00120     memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
    00121
    00122     pointer address(reference x) const { return &x; }
    00123     const_pointer address(const_reference x) const { return &x; }
    00124
    00126     pointer allocate( size_type n, const void* /*hint*/ = 0) {
    00127         return static_cast<pointer>( my_pool->malloc( n*sizeof(value_type) ) );
    00128     }
    00130     void deallocate( pointer p, size_type ) {
    00131         my_pool->free(p);
    00132     }
    00134     size_type max_size() const throw() {
    00135         size_type max = static_cast<size_type>(-1) / sizeof (value_type);
    00136         return (max > 0 ? max : 1);
    00137     }
    00139 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00140     template<typename... Args>
    00141     void construct(pointer p, Args&&... args)
    00142  #if __TBB_CPP11_STD_FORWARD_BROKEN
    00143         { ::new((void *)p) T((args)...); }
    00144  #else
    00145         { ::new((void *)p) T(std::forward<Args>(args)...); }
    00146  #endif
    00147 #else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00148     void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); }
    00149 #endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00150
    00152     void destroy( pointer p ) { p->~value_type(); }
    00153
    00154 };
    00155
    00156 #if _MSC_VER && !defined(__INTEL_COMPILER)
    00157     #pragma warning (pop)
    00158 #endif // warning 4100 is back
    00159
    00161
    00162 template<typename P>
    00163 class memory_pool_allocator<void, P> {
    00164 public:
    00165     typedef P pool_type;
    00166     typedef void* pointer;
    00167     typedef const void* const_pointer;
    00168     typedef void value_type;
    00169     template<typename U> struct rebind {
    00170         typedef memory_pool_allocator<U, P> other;
    00171     };
    00172
    00173     memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {}
    00174     memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
    00175     template<typename U>
    00176     memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
    00177
    00178 protected:
    00179     pool_type *my_pool;
    00180     template<typename U, typename R>
    00181     friend class memory_pool_allocator;
    00182     template<typename V, typename U, typename R>
    00183     friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00184     template<typename V, typename U, typename R>
    00185     friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00186 };
    00187
    00188 template<typename T, typename U, typename P>
    00189 inline bool operator==( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool==b.my_pool;}
    00190
    00191 template<typename T, typename U, typename P>
    00192 inline bool operator!=( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool!=b.my_pool;}
    00193
    00194
    00196 template <typename Alloc>
    00197 class memory_pool : public internal::pool_base {
    00198     Alloc my_alloc; // TODO: base-class optimization
    00199     static void *allocate_request(intptr_t pool_id, size_t & bytes);
    00200     static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes);
    00201
    00202 public:
    00204     memory_pool(const Alloc &src = Alloc());
    00205
    00207     ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter
    00208
    00209 };
    00210
    00211 class fixed_pool : public internal::pool_base {
    00212     void *my_buffer;
    00213     size_t my_size;
    00214     inline static void *allocate_request(intptr_t pool_id, size_t & bytes);
    00215
    00216 public:
    00218     inline fixed_pool(void *buf, size_t size);
    00220     ~fixed_pool() { destroy(); }
    00221 };
    00222
    00224
    00225 template <typename Alloc>
    00226 memory_pool<Alloc>::memory_pool(const Alloc &src) : my_alloc(src) {
    00227     rml::MemPoolPolicy args(allocate_request, deallocate_request,
    00228                             sizeof(typename Alloc::value_type));
    00229     rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
    00230     if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
    00231 }
    00232 template <typename Alloc>
    00233 void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
    00234     memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
    00235     const size_t unit_size = sizeof(typename Alloc::value_type);
    00236     __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL);
    00237     void *ptr;
    00238     __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); }
    00239     __TBB_CATCH(...) { return 0; }
    00240     return ptr;
    00241 }
    00242 template <typename Alloc>
    00243 int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) {
    00244     memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
    00245     const size_t unit_size = sizeof(typename Alloc::value_type);
    00246     __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL);
    00247     self.my_alloc.deallocate( static_cast<typename Alloc::value_type*>(raw_ptr), raw_bytes/unit_size );
    00248     return 0;
    00249 }
    00250 inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) {
    00251     rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true);
    00252     rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
    00253     if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
    00254 }
    00255 inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) {
    00256     fixed_pool &self = *reinterpret_cast<fixed_pool*>(pool_id);
    00257     if( !__TBB_CompareAndSwapW(&self.my_size, 0, (bytes=self.my_size)) )
    00258         return 0; // all the memory was given already
    00259     return self.my_buffer;
    00260 }
    00261
    00262 } //namespace interface6
    00263 using interface6::memory_pool_allocator;
    00264 using interface6::memory_pool;
    00265 using interface6::fixed_pool;
    00266 } //namespace tbb
    00267
    00268 #undef __TBBMALLOC_ASSERT
    00269 #endif// __TBB_memory_pool_H

Copyright © 2005-2012 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.