fixed_mem_pool.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 // vim:tabstop=4:shiftwidth=4:expandtab:
00003 
00004 /*
00005  * Copyright (C) 2004-2007 Wu Yongwei <adah at users dot sourceforge dot net>
00006  *
00007  * This software is provided 'as-is', without any express or implied
00008  * warranty.  In no event will the authors be held liable for any
00009  * damages arising from the use of this software.
00010  *
00011  * Permission is granted to anyone to use this software for any purpose,
00012  * including commercial applications, and to alter it and redistribute
00013  * it freely, subject to the following restrictions:
00014  *
00015  * 1. The origin of this software must not be misrepresented; you must
00016  *    not claim that you wrote the original software. If you use this
00017  *    software in a product, an acknowledgement in the product
00018  *    documentation would be appreciated but is not required.
00019  * 2. Altered source versions must be plainly marked as such, and must
00020  *    not be misrepresented as being the original software.
00021  * 3. This notice may not be removed or altered from any source
00022  *    distribution.
00023  *
00024  * This file is part of Stones of Nvwa:
00025  *      http://sourceforge.net/projects/nvwa
00026  *
00027  */
00028 
00053 #ifndef _FIXED_MEM_POOL_H
00054 #define _FIXED_MEM_POOL_H
00055 
00056 #include <new>
00057 #include <assert.h>
00058 #include <stdlib.h>
00059 #include "class_level_lock.h"
00060 #include "mem_pool_base.h"
00061 
00065 #ifndef MEM_POOL_ALIGNMENT
00066 #define MEM_POOL_ALIGNMENT 4
00067 #endif
00068 
00075 template <class _Tp>
00076 class fixed_mem_pool
00077 {
00078 public:
00079     typedef typename class_level_lock<fixed_mem_pool<_Tp> >::lock lock;
00080     static void*  allocate();
00081     static void   deallocate(void*);
00082     static bool   initialize(size_t __size);
00083     static int    deinitialize();
00084     static int    get_alloc_count();
00085     static bool   is_initialized();
00086 protected:
00087     static bool   bad_alloc_handler();
00088 private:
00089     static size_t _S_align(size_t __size);
00090     static void*  _S_mem_pool_ptr;
00091     static void*  _S_first_avail_ptr;
00092     static int    _S_alloc_cnt;
00093 };
00094 
00096 template <class _Tp>
00097 void* fixed_mem_pool<_Tp>::_S_mem_pool_ptr = NULL;
00098 
00100 template <class _Tp>
00101 void* fixed_mem_pool<_Tp>::_S_first_avail_ptr = NULL;
00102 
00104 template <class _Tp>
00105 int   fixed_mem_pool<_Tp>::_S_alloc_cnt = 0;
00106 
00112 template <class _Tp>
00113 inline void* fixed_mem_pool<_Tp>::allocate()
00114 {
00115     lock __guard;
00116     for (;;)
00117     {
00118         if (void* __result = _S_first_avail_ptr)
00119         {
00120             _S_first_avail_ptr = *(void**)_S_first_avail_ptr;
00121             ++_S_alloc_cnt;
00122             return __result;
00123         }
00124         else
00125             if (!bad_alloc_handler())
00126                 return NULL;
00127     }
00128 }
00129 
00135 template <class _Tp>
00136 inline void fixed_mem_pool<_Tp>::deallocate(void* __block_ptr)
00137 {
00138     if (__block_ptr == NULL)
00139         return;
00140     lock __guard;
00141     assert(_S_alloc_cnt != 0);
00142     --_S_alloc_cnt;
00143     *(void**)__block_ptr = _S_first_avail_ptr;
00144     _S_first_avail_ptr = __block_ptr;
00145 }
00146 
00153 template <class _Tp>
00154 bool fixed_mem_pool<_Tp>::initialize(size_t __size)
00155 {
00156     size_t __block_size = _S_align(sizeof(_Tp));
00157     assert(!is_initialized());
00158     assert(__size > 0 && __block_size >= sizeof(void*));
00159     _S_mem_pool_ptr = mem_pool_base::alloc_sys(__size * __block_size);
00160     _S_first_avail_ptr = _S_mem_pool_ptr;
00161     if (_S_mem_pool_ptr == NULL)
00162         return false;
00163     char* __block = (char*)_S_mem_pool_ptr;
00164     while (--__size != 0)
00165     {
00166         char* __next = __block + __block_size;
00167         *(void**)__block = __next;
00168         __block = __next;
00169     }
00170     *(void**)__block = NULL;
00171     return true;
00172 }
00173 
00181 template <class _Tp>
00182 int fixed_mem_pool<_Tp>::deinitialize()
00183 {
00184     if (_S_alloc_cnt != 0)
00185         return _S_alloc_cnt;
00186     assert(is_initialized());
00187     mem_pool_base::dealloc_sys(_S_mem_pool_ptr);
00188     _S_mem_pool_ptr = NULL;
00189     _S_first_avail_ptr = NULL;
00190     return 0;
00191 }
00192 
00198 template <class _Tp>
00199 inline int fixed_mem_pool<_Tp>::get_alloc_count()
00200 {
00201     return _S_alloc_cnt;
00202 }
00203 
00209 template <class _Tp>
00210 inline bool fixed_mem_pool<_Tp>::is_initialized()
00211 {
00212     return _S_mem_pool_ptr != NULL;;
00213 }
00214 
00223 template <class _Tp>
00224 bool fixed_mem_pool<_Tp>::bad_alloc_handler()
00225 {
00226     return false;
00227 }
00228 
00235 template <class _Tp>
00236 inline size_t fixed_mem_pool<_Tp>::_S_align(size_t __size)
00237 {
00238     return (__size + MEM_POOL_ALIGNMENT - 1)
00239            / MEM_POOL_ALIGNMENT * MEM_POOL_ALIGNMENT;
00240 }
00241 
00252 #define DECLARE_FIXED_MEM_POOL(_Cls) \
00253 public: \
00254     static void* operator new(size_t __size) \
00255     { \
00256         assert(__size == sizeof(_Cls)); \
00257         if (void* __ptr = fixed_mem_pool<_Cls>::allocate()) \
00258             return __ptr; \
00259         else \
00260             throw std::bad_alloc(); \
00261     } \
00262     static void  operator delete(void* __ptr) \
00263     { \
00264         if (__ptr != NULL) \
00265             fixed_mem_pool<_Cls>::deallocate(__ptr); \
00266     }
00267 
00274 #define DECLARE_FIXED_MEM_POOL__NOTHROW(_Cls) \
00275 public: \
00276     static void* operator new(size_t __size) throw() \
00277     { \
00278         assert(__size == sizeof(_Cls)); \
00279         return fixed_mem_pool<_Cls>::allocate(); \
00280     } \
00281     static void  operator delete(void* __ptr) \
00282     { \
00283         if (__ptr != NULL) \
00284             fixed_mem_pool<_Cls>::deallocate(__ptr); \
00285     }
00286 
00299 #define DECLARE_FIXED_MEM_POOL__THROW_NOCHECK(_Cls) \
00300 public: \
00301     static void* operator new(size_t __size) \
00302     { \
00303         assert(__size == sizeof(_Cls)); \
00304         return fixed_mem_pool<_Cls>::allocate(); \
00305     } \
00306     static void  operator delete(void* __ptr) \
00307     { \
00308         if (__ptr != NULL) \
00309             fixed_mem_pool<_Cls>::deallocate(__ptr); \
00310     }
00311 
00312 #endif // _FIXED_MEM_POOL_H

Generated on Mon Dec 31 15:07:24 2007 for Nvwa by  doxygen 1.5.1