/******************************************************************** created: 2008/06/20 created: 20:6:2008 15:28 filename: d:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib\utilib\small_pool.h file path: d:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib\utilib file base: small_pool file ext: h author: purpose: *********************************************************************/ #ifndef __UTILIB_MEM_POOL_LIST_H__ #define __UTILIB_MEM_POOL_LIST_H__ #include "block_pool.h" #include "int2type.h" namespace utilib { template< size_t Align = 4, size_t MaxBytes = 512, size_t Count = 50, class Grow = grow::arithmetic<1>, class Lock = pool_lock > class small_pool : public noncopyable { public: enum { ALIGN = (Align + 3) & ~((unsigned)3) }; enum { MAXBYTES = ((MaxBytes + ALIGN - 1) & ~((unsigned)(ALIGN - 1))) + sizeof(size_t) }; enum { LSTNUM = MAXBYTES / ALIGN }; private: class small_alloc_base { public: virtual ~small_alloc_base() { } virtual void * allocate() = 0; virtual void deallocate(void * p) = 0; }; template class small_alloc : public small_alloc_base { public: void * allocate() { return pool_.allocate(); } void deallocate(void * p) { pool_.deallocate(p); } private: block_pool<_Bytes, Count, Grow, Lock> pool_; }; struct pool { small_alloc_base * pool_; }; #ifdef WIN32 template struct create_pool; template< > struct create_pool { create_pool(pool []) { } }; template struct create_pool { create_pool(pool p[]) { p[ListIndex].pool_ = new small_alloc(); create_pool cp(p); } }; template struct destroy_pool { destroy_pool(pool p[]) { delete p[ListIndex].pool_; p[ListIndex].pool_ = 0; destroy_pool dp(p); } }; template<> struct destroy_pool { destroy_pool(pool []) { } }; #else template void create_pool(int2type & ty, pool * p) { p[ListIndex].pool_ = new small_alloc(); int2type tmp; create_pool(tmp, p); } void create_pool(int2type &, pool *) { } template void destroy_pool(int2type & ty, pool * p) { delete p[ListIndex].pool_; p[ListIndex].pool_ = 0; int2type tmp; destroy_pool(tmp, p); } void destroy_pool(int2type &, pool *) { } #endif public: small_pool() { #ifdef WIN32 create_pool<0> cp(pool_); #else int2type<0> tmp; create_pool<0>(tmp, (pool *)pool_); #endif } ~small_pool() { clean(); } void clean() { #ifdef WIN32 destroy_pool<0> dp(pool_); #else int2type<0> tmp; destroy_pool<0>(tmp, (pool *)pool_); #endif } void * allocate(size_t bytes) { bytes += sizeof(size_t); bytes = (bytes + ALIGN - 1) & ~(ALIGN - 1); if (bytes > MAXBYTES) return 0; size_t index = bytes / ALIGN - 1; size_t * p = (size_t *)pool_[index].pool_->allocate(); if (p) { *p = index; return (p += 1); } return 0; } void deallocate(void * p) { if (p) { size_t * tmp = (size_t *)p; tmp -= 1; pool_[*tmp].pool_->deallocate(tmp); } } private: pool pool_[LSTNUM]; }; } #endif