memory_pool.h Source File

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

- 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     The source code contained or described herein and all documents related
    00005     to the source code ("Material") are owned by Intel Corporation or its
    00006     suppliers or licensors.  Title to the Material remains with Intel
    00007     Corporation or its suppliers and licensors.  The Material is protected
    00008     by worldwide copyright laws and treaty provisions.  No part of the
    00009     Material may be used, copied, reproduced, modified, published, uploaded,
    00010     posted, transmitted, distributed, or disclosed in any way without
    00011     Intel's prior express written permission.
    00012
    00013     No license under any patent, copyright, trade secret or other
    00014     intellectual property right is granted to or conferred upon you by
    00015     disclosure or delivery of the Materials, either expressly, by
    00016     implication, inducement, estoppel or otherwise.  Any license under such
    00017     intellectual property rights must be express and approved by Intel in
    00018     writing.
    00019 */
    00020
    00021 #ifndef __TBB_memory_pool_H
    00022 #define __TBB_memory_pool_H
    00023
    00024 #if !TBB_PREVIEW_MEMORY_POOL
    00025 #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h
    00026 #endif
    00027
    00029 #include "scalable_allocator.h"
    00030 #include "tbb_stddef.h"
    00031 #include "tbb_machine.h" // TODO: avoid linkage with libtbb on IA-64
    00032 #include <new> // std::bad_alloc
    00033 #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
    00034 #include <utility> // std::forward
    00035 #endif
    00036
    00037 #if __TBB_EXTRA_DEBUG
    00038 #define __TBBMALLOC_ASSERT ASSERT
    00039 #else
    00040 #define __TBBMALLOC_ASSERT(a,b) ((void)0)
    00041 #endif
    00042
    00043 namespace tbb {
    00044 namespace interface6 {
    00046 namespace internal {
    00047
    00049 class pool_base : tbb::internal::no_copy {
    00050     // Pool interface is separate from standard allocator classes because it has
    00051     // to maintain internal state, no copy or assignment. Move and swap are possible.
    00052 public:
    00054     void recycle() { rml::pool_reset(my_pool); }
    00055
    00057     void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); }
    00058
    00060     void free(void* ptr) { rml::pool_free(my_pool, ptr); }
    00061
    00063     // Enables some low-level optimization possibilities
    00064     void *realloc(void* ptr, size_t size) {
    00065         return rml::pool_realloc(my_pool, ptr, size);
    00066     }
    00067
    00068 protected:
    00070     void destroy() { rml::pool_destroy(my_pool); }
    00071
    00072     rml::MemoryPool *my_pool;
    00073 };
    00074
    00075 } // namespace internal
    00077
    00078 #if _MSC_VER && !defined(__INTEL_COMPILER)
    00079     // Workaround for erroneous "unreferenced parameter" warning in method destroy.
    00080     #pragma warning (push)
    00081     #pragma warning (disable: 4100)
    00082 #endif
    00083
    00085
    00086 template<typename T, typename P = internal::pool_base>
    00087 class memory_pool_allocator {
    00088 protected:
    00089     typedef P pool_type;
    00090     pool_type *my_pool;
    00091     template<typename U, typename R>
    00092     friend class memory_pool_allocator;
    00093     template<typename V, typename U, typename R>
    00094     friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00095     template<typename V, typename U, typename R>
    00096     friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00097 public:
    00098     typedef typename tbb::internal::allocator_type<T>::value_type value_type;
    00099     typedef value_type* pointer;
    00100     typedef const value_type* const_pointer;
    00101     typedef value_type& reference;
    00102     typedef const value_type& const_reference;
    00103     typedef size_t size_type;
    00104     typedef ptrdiff_t difference_type;
    00105     template<typename U> struct rebind {
    00106         typedef memory_pool_allocator<U, P> other;
    00107     };
    00108
    00109     memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {}
    00110     memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
    00111     template<typename U>
    00112     memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
    00113
    00114     pointer address(reference x) const { return &x; }
    00115     const_pointer address(const_reference x) const { return &x; }
    00116
    00118     pointer allocate( size_type n, const void* /*hint*/ = 0) {
    00119         return static_cast<pointer>( my_pool->malloc( n*sizeof(value_type) ) );
    00120     }
    00122     void deallocate( pointer p, size_type ) {
    00123         my_pool->free(p);
    00124     }
    00126     size_type max_size() const throw() {
    00127         size_type max = static_cast<size_type>(-1) / sizeof (value_type);
    00128         return (max > 0 ? max : 1);
    00129     }
    00131 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00132     template<typename... Args>
    00133     void construct(pointer p, Args&&... args)
    00134  #if __TBB_CPP11_STD_FORWARD_BROKEN
    00135         { ::new((void *)p) T((args)...); }
    00136  #else
    00137         { ::new((void *)p) T(std::forward<Args>(args)...); }
    00138  #endif
    00139 #else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00140     void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); }
    00141 #endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT
    00142
    00144     void destroy( pointer p ) { p->~value_type(); }
    00145
    00146 };
    00147
    00148 #if _MSC_VER && !defined(__INTEL_COMPILER)
    00149     #pragma warning (pop)
    00150 #endif // warning 4100 is back
    00151
    00153
    00154 template<typename P>
    00155 class memory_pool_allocator<void, P> {
    00156 public:
    00157     typedef P pool_type;
    00158     typedef void* pointer;
    00159     typedef const void* const_pointer;
    00160     typedef void value_type;
    00161     template<typename U> struct rebind {
    00162         typedef memory_pool_allocator<U, P> other;
    00163     };
    00164
    00165     memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {}
    00166     memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
    00167     template<typename U>
    00168     memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
    00169
    00170 protected:
    00171     pool_type *my_pool;
    00172     template<typename U, typename R>
    00173     friend class memory_pool_allocator;
    00174     template<typename V, typename U, typename R>
    00175     friend bool operator==( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00176     template<typename V, typename U, typename R>
    00177     friend bool operator!=( const memory_pool_allocator<V,R>& a, const memory_pool_allocator<U,R>& b);
    00178 };
    00179
    00180 template<typename T, typename U, typename P>
    00181 inline bool operator==( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool==b.my_pool;}
    00182
    00183 template<typename T, typename U, typename P>
    00184 inline bool operator!=( const memory_pool_allocator<T,P>& a, const memory_pool_allocator<U,P>& b) {return a.my_pool!=b.my_pool;}
    00185
    00186
    00188 template <typename Alloc>
    00189 class memory_pool : public internal::pool_base {
    00190     Alloc my_alloc; // TODO: base-class optimization
    00191     static void *allocate_request(intptr_t pool_id, size_t & bytes);
    00192     static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes);
    00193
    00194 public:
    00196     memory_pool(const Alloc &src = Alloc());
    00197
    00199     ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter
    00200
    00201 };
    00202
    00203 class fixed_pool : public internal::pool_base {
    00204     void *my_buffer;
    00205     size_t my_size;
    00206     inline static void *allocate_request(intptr_t pool_id, size_t & bytes);
    00207
    00208 public:
    00210     inline fixed_pool(void *buf, size_t size);
    00212     ~fixed_pool() { destroy(); }
    00213 };
    00214
    00216
    00217 template <typename Alloc>
    00218 memory_pool<Alloc>::memory_pool(const Alloc &src) : my_alloc(src) {
    00219     rml::MemPoolPolicy args(allocate_request, deallocate_request,
    00220                             sizeof(typename Alloc::value_type));
    00221     rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
    00222     if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
    00223 }
    00224 template <typename Alloc>
    00225 void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
    00226     memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
    00227     const size_t unit_size = sizeof(typename Alloc::value_type);
    00228     __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL);
    00229     void *ptr;
    00230     __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); }
    00231     __TBB_CATCH(...) { return 0; }
    00232     return ptr;
    00233 }
    00234 template <typename Alloc>
    00235 int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) {
    00236     memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
    00237     const size_t unit_size = sizeof(typename Alloc::value_type);
    00238     __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL);
    00239     self.my_alloc.deallocate( static_cast<typename Alloc::value_type*>(raw_ptr), raw_bytes/unit_size );
    00240     return 0;
    00241 }
    00242 inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) {
    00243     rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true);
    00244     rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
    00245     if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
    00246 }
    00247 inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) {
    00248     fixed_pool &self = *reinterpret_cast<fixed_pool*>(pool_id);
    00249     if( !__TBB_CompareAndSwapW(&self.my_size, 0, (bytes=self.my_size)) )
    00250         return 0; // all the memory was given already
    00251     return self.my_buffer;
    00252 }
    00253
    00254 } //namespace interface6
    00255 using interface6::memory_pool_allocator;
    00256 using interface6::memory_pool;
    00257 using interface6::fixed_pool;
    00258 } //namespace tbb
    00259
    00260 #undef __TBBMALLOC_ASSERT
    00261 #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.