10 #ifndef __PION_PIONPOOLALLOCATOR_HEADER__
11 #define __PION_PIONPOOLALLOCATOR_HEADER__
14 #include <boost/array.hpp>
15 #include <boost/scoped_ptr.hpp>
16 #include <boost/static_assert.hpp>
17 #include <boost/noncopyable.hpp>
18 #include <boost/thread/mutex.hpp>
19 #include <boost/pool/pool.hpp>
20 #include <pion/PionConfig.hpp>
21 #include <pion/PionException.hpp>
23 #if defined(PION_HAVE_MALLOC_TRIM)
28 #if defined(PION_HAVE_LOCKFREE)
31 #pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning)
33 #include <boost/lockfree/detail/tagged_ptr.hpp>
37 #include <boost/lockfree/atomic_int.hpp>
51 template <std::
size_t MinSize = 16, std::
size_t MaxSize = 256>
53 :
private boost::noncopyable
64 for (std::size_t n = 0; n < NumberOfAllocs; ++n) {
83 #if defined(PION_HAVE_LOCKFREE)
86 FreeListPtr old_free_ptr(pool_ptr->
m_free_ptr);
91 if (pool_ptr->
m_free_ptr.cas(old_free_ptr, old_free_ptr->next.get_ptr()))
92 return reinterpret_cast<void*
>(old_free_ptr.get_ptr());
96 boost::unique_lock<boost::mutex> pool_lock(pool_ptr->
m_mutex);
97 return pool_ptr->
m_pool.malloc();
106 inline void free(
void *ptr, std::size_t n)
114 #if defined(PION_HAVE_LOCKFREE)
117 FreeListPtr old_free_ptr(pool_ptr->
m_free_ptr);
121 FreeListNode *node_ptr =
reinterpret_cast<FreeListNode*
>(ptr);
122 node_ptr->next.set_ptr(old_free_ptr.get_ptr());
125 if (pool_ptr->
m_free_ptr.cas(old_free_ptr, node_ptr))
129 boost::unique_lock<boost::mutex> pool_lock(pool_ptr->
m_mutex);
130 return pool_ptr->
m_pool.free(ptr);
175 #if defined(PION_HAVE_LOCKFREE)
176 struct FreeListNode {
184 typedef void * FreeListPtr;
193 #if defined(PION_HAVE_LOCKFREE)
198 enum { NumberOfAllocs = ((MaxSize-1) / MinSize) + 1 };
239 PION_ASSERT(n <= MaxSize);
240 return m_pools[ (n-1) / MinSize ].
get();
247 boost::array<boost::scoped_ptr<FixedSizeAlloc>, NumberOfAllocs> m_pools;
boost::pool m_pool
underlying pool allocator used for memory management
void * malloc(std::size_t n)
FreeListPtr m_free_ptr
pointer to a list of free nodes (for lock-free cache)
std::size_t m_size
size of memory blocks managed by this allocator, in bytes
FixedSizeAlloc(std::size_t size)
void free(void *ptr, std::size_t n)
bool release_memory(size_t pad=10240000UL)
virtual ~PionPoolAllocator()
virtual destructor
BOOST_STATIC_ASSERT(MaxSize >=MinSize)
PionPoolAllocator(void)
default constructor
the following enables use of the lock-free cache
FixedSizeAlloc * getPool(const std::size_t n)
boost::mutex m_mutex
used to protect access to the memory pool