// // boost/memory/system_pool.hpp // // Copyright (c) 2004 - 2008 xushiwei (xushiweizh@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/memory/index.htm for documentation. // #ifndef __BOOST_MEMORY_SYSTEM_POOL_HPP__ #define __BOOST_MEMORY_SYSTEM_POOL_HPP__ #ifndef BOOST_MEMORY_BASIC_HPP #include "basic.hpp" #endif #ifndef BOOST_MEMORY_POLICY_HPP #include "policy.hpp" #endif #ifndef BOOST_LOCKFREE_STACK_HPP #include #endif NS_BOOST_MEMORY_BEGIN // ------------------------------------------------------------------------- // class normal_stack class normal_stack { private: normal_stack(const normal_stack&); void operator=(const normal_stack&); typedef NS_BOOST_DETAIL::default_threadmodel::cs cs; typedef cs::scoped_lock cslock; public: class node { private: node* m_prev; friend class normal_stack; public: node() : m_prev(NULL) {} node* prev() const { return m_prev; } }; private: node* m_top; cs m_cs; public: normal_stack() : m_top(NULL) {} void BOOST_LOCKFREE_CALL push(node* val) { cslock aLock(m_cs); val->m_prev = m_top; m_top = val; } node* BOOST_LOCKFREE_CALL clear() { cslock aLock(m_cs); node* the_top = m_top; m_top = NULL; return the_top; } node* BOOST_LOCKFREE_CALL pop() { cslock aLock(m_cs); node* the_top = m_top; if (the_top == NULL) return NULL; m_top = m_top->m_prev; return the_top; } }; // ------------------------------------------------------------------------- // class system_pool_imp template class system_pool_imp { private: typedef typename PolicyT::allocator_type AllocT; enum { cbBlock = PolicyT::MemBlockSize }; typedef typename StackT::node Block; StackT m_freeList; private: system_pool_imp(const system_pool_imp&); void operator=(const system_pool_imp&); public: system_pool_imp() { } ~system_pool_imp() { clear(); } public: void* BOOST_MEMORY_CALL allocate(size_t cb) { BOOST_MEMORY_ASSERT(cb >= (size_t)cbBlock); if (cb > (size_t)cbBlock) return AllocT::allocate(cb); { Block* blk = m_freeList.pop(); if (blk) { BOOST_MEMORY_ASSERT(AllocT::alloc_size(blk) >= cb); return blk; } } return AllocT::allocate(cbBlock); } void BOOST_MEMORY_CALL deallocate(void* p) { m_freeList.push((Block*)p); } static size_t BOOST_MEMORY_CALL alloc_size(void* p) { return AllocT::alloc_size(p); } void BOOST_MEMORY_CALL clear() { Block* freeList = m_freeList.clear(); while (freeList) { Block* blk = freeList; freeList = freeList->prev(); AllocT::deallocate(blk); } } }; // ------------------------------------------------------------------------- // class system_pool_s template class system_pool_s { private: typedef system_pool_imp SystemPoolImpl; static SystemPoolImpl s_impl; public: static void* BOOST_MEMORY_CALL allocate(size_t cb) { return s_impl.allocate(cb); } static void BOOST_MEMORY_CALL deallocate(void* p) { s_impl.deallocate(p); } static size_t BOOST_MEMORY_CALL alloc_size(void* p) { return s_impl.alloc_size(p); } }; template system_pool_imp system_pool_s::s_impl; // ------------------------------------------------------------------------- // class system_pool NS_BOOST_MEMORY_POLICY_BEGIN class stdlib : public sys { public: typedef stdlib_alloc allocator_type; }; NS_BOOST_MEMORY_POLICY_END // ------------------------------------------------------------------------- #if defined(BOOST_MEMORY_NO_LOCKFREE) typedef system_pool_s system_pool; #else typedef system_pool_s system_pool; #endif // ------------------------------------------------------------------------- // $Log: $ NS_BOOST_MEMORY_END #endif /* __BOOST_MEMORY_SYSTEM_POOL_HPP__ */