static_mem_pool.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00039 #ifndef _STATIC_MEM_POOL_H
00040 #define _STATIC_MEM_POOL_H
00041
00042 #include <new>
00043 #include <stdexcept>
00044 #include <string>
00045 #include <vector>
00046 #include <assert.h>
00047 #include <stddef.h>
00048 #include "class_level_lock.h"
00049 #include "mem_pool_base.h"
00050
00051
00052 # if (defined(_MSC_VER) && _MSC_VER < 1300) \
00053 || (defined(__BORLANDC__) && __BORLANDC__ < 0x600)
00054 # define __PRIVATE public
00055 # else
00056 # define __PRIVATE private
00057 # endif
00058
00059
00060 # ifdef _STATIC_MEM_POOL_DEBUG
00061 # include <iostream>
00062 # define _STATIC_MEM_POOL_TRACE(_Lck, _Msg) \
00063 { \
00064 if (_Lck) { \
00065 static_mem_pool_set::lock __guard; \
00066 std::cerr << "static_mem_pool: " << _Msg << std::endl; \
00067 } else { \
00068 std::cerr << "static_mem_pool: " << _Msg << std::endl; \
00069 } \
00070 }
00071 # else
00072 # define _STATIC_MEM_POOL_TRACE(_Lck, _Msg) \
00073 ((void)0)
00074 # endif
00075
00080 class static_mem_pool_set
00081 {
00082 public:
00083 typedef class_level_lock<static_mem_pool_set>::lock lock;
00084 static static_mem_pool_set& instance();
00085 void recycle();
00086 void add(mem_pool_base* __memory_pool_p);
00087
00088 __PRIVATE:
00089 ~static_mem_pool_set();
00090 private:
00091 static_mem_pool_set();
00092
00093 typedef std::vector<mem_pool_base*> container_type;
00094 container_type _M_memory_pool_set;
00095
00096
00097 static_mem_pool_set(const static_mem_pool_set&);
00098 const static_mem_pool_set& operator=(const static_mem_pool_set&);
00099 };
00100
00111 template <size_t _Sz, int _Gid = -1>
00112 class static_mem_pool : public mem_pool_base
00113 {
00114 typedef typename class_level_lock<static_mem_pool<_Sz, _Gid>, (_Gid < 0)>
00115 ::lock lock;
00116 public:
00125 static static_mem_pool& instance()
00126 {
00127 lock __guard;
00128 if (!_S_instance_p)
00129 {
00130 _S_instance_p = _S_create_instance();
00131 }
00132 return *_S_instance_p;
00133 }
00141 static static_mem_pool& instance_known()
00142 {
00143 assert(_S_instance_p != NULL);
00144 return *_S_instance_p;
00145 }
00154 void* allocate()
00155 {
00156 {
00157 lock __guard;
00158 if (_S_memory_block_p)
00159 {
00160 void* __result = _S_memory_block_p;
00161 _S_memory_block_p = _S_memory_block_p->_M_next;
00162 return __result;
00163 }
00164 }
00165 return _S_alloc_sys(_S_align(_Sz));
00166 }
00172 void deallocate(void* __ptr)
00173 {
00174 assert(__ptr != NULL);
00175 lock __guard;
00176 _Block_list* __block = reinterpret_cast<_Block_list*>(__ptr);
00177 __block->_M_next = _S_memory_block_p;
00178 _S_memory_block_p = __block;
00179 }
00180 virtual void recycle();
00181
00182 private:
00183 static_mem_pool()
00184 {
00185 _STATIC_MEM_POOL_TRACE(true, "static_mem_pool<" << _Sz << ','
00186 << _Gid << "> is created");
00187 }
00188 ~static_mem_pool()
00189 {
00190 # ifdef _DEBUG
00191
00192
00193 _Block_list* __block = _S_memory_block_p;
00194 while (__block)
00195 {
00196 _Block_list* __next = __block->_M_next;
00197 dealloc_sys(__block);
00198 __block = __next;
00199 }
00200 _S_memory_block_p = NULL;
00201 # endif
00202 _S_instance_p = NULL;
00203 _S_destroyed = true;
00204 _STATIC_MEM_POOL_TRACE(false, "static_mem_pool<" << _Sz << ','
00205 << _Gid << "> is destroyed");
00206 }
00207 static size_t _S_align(size_t __size)
00208 {
00209 return __size >= sizeof(_Block_list) ? __size : sizeof(_Block_list);
00210 }
00211 static void* _S_alloc_sys(size_t __size);
00212 static static_mem_pool* _S_create_instance();
00213
00214 static bool _S_destroyed;
00215 static static_mem_pool* _S_instance_p;
00216 static mem_pool_base::_Block_list* _S_memory_block_p;
00217
00218
00219 static_mem_pool(const static_mem_pool&);
00220 const static_mem_pool& operator=(const static_mem_pool&);
00221 };
00222
00223 template <size_t _Sz, int _Gid> bool
00224 static_mem_pool<_Sz, _Gid>::_S_destroyed = false;
00225 template <size_t _Sz, int _Gid> mem_pool_base::_Block_list*
00226 static_mem_pool<_Sz, _Gid>::_S_memory_block_p = NULL;
00227 template <size_t _Sz, int _Gid> static_mem_pool<_Sz, _Gid>*
00228 static_mem_pool<_Sz, _Gid>::_S_instance_p = _S_create_instance();
00229
00235 template <size_t _Sz, int _Gid>
00236 void static_mem_pool<_Sz, _Gid>::recycle()
00237 {
00238
00239
00240
00241 lock __guard;
00242 _Block_list* __block = _S_memory_block_p;
00243 while (__block)
00244 {
00245 if (_Block_list* __temp = __block->_M_next)
00246 {
00247 _Block_list* __next = __temp->_M_next;
00248 __block->_M_next = __next;
00249 dealloc_sys(__temp);
00250 __block = __next;
00251 }
00252 else
00253 {
00254 break;
00255 }
00256 }
00257 _STATIC_MEM_POOL_TRACE(false, "static_mem_pool<" << _Sz << ','
00258 << _Gid << "> is recycled");
00259 }
00260
00261 template <size_t _Sz, int _Gid>
00262 void* static_mem_pool<_Sz, _Gid>::_S_alloc_sys(size_t __size)
00263 {
00264 static_mem_pool_set::lock __guard;
00265 void* __result = mem_pool_base::alloc_sys(__size);
00266 if (!__result)
00267 {
00268 static_mem_pool_set::instance().recycle();
00269 __result = mem_pool_base::alloc_sys(__size);
00270 }
00271 return __result;
00272 }
00273
00274 template <size_t _Sz, int _Gid>
00275 static_mem_pool<_Sz, _Gid>* static_mem_pool<_Sz, _Gid>::_S_create_instance()
00276 {
00277 if (_S_destroyed)
00278 throw std::runtime_error("dead reference detected");
00279
00280 static_mem_pool_set::instance();
00281 static_mem_pool* __inst_p = new static_mem_pool();
00282 try
00283 {
00284 static_mem_pool_set::instance().add(__inst_p);
00285 }
00286 catch (...)
00287 {
00288 _STATIC_MEM_POOL_TRACE(true,
00289 "Exception occurs in static_mem_pool_set::add");
00290
00291 delete static_cast<mem_pool_base*>(__inst_p);
00292 throw;
00293 }
00294 return __inst_p;
00295 }
00296
00297 #define DECLARE_STATIC_MEM_POOL(_Cls) \
00298 public: \
00299 static void* operator new(size_t __size) \
00300 { \
00301 assert(__size == sizeof(_Cls)); \
00302 void* __ptr; \
00303 __ptr = static_mem_pool<sizeof(_Cls)>:: \
00304 instance_known().allocate(); \
00305 if (__ptr == NULL) \
00306 throw std::bad_alloc(); \
00307 return __ptr; \
00308 } \
00309 static void operator delete(void* __ptr) \
00310 { \
00311 if (__ptr) \
00312 static_mem_pool<sizeof(_Cls)>:: \
00313 instance_known().deallocate(__ptr); \
00314 }
00315
00316 #define DECLARE_STATIC_MEM_POOL__NOTHROW(_Cls) \
00317 public: \
00318 static void* operator new(size_t __size) throw() \
00319 { \
00320 assert(__size == sizeof(_Cls)); \
00321 return static_mem_pool<sizeof(_Cls)>:: \
00322 instance_known().allocate(); \
00323 } \
00324 static void operator delete(void* __ptr) \
00325 { \
00326 if (__ptr) \
00327 static_mem_pool<sizeof(_Cls)>:: \
00328 instance_known().deallocate(__ptr); \
00329 }
00330
00331 #define DECLARE_STATIC_MEM_POOL_GROUPED(_Cls, _Gid) \
00332 public: \
00333 static void* operator new(size_t __size) \
00334 { \
00335 assert(__size == sizeof(_Cls)); \
00336 void* __ptr; \
00337 __ptr = static_mem_pool<sizeof(_Cls), (_Gid)>:: \
00338 instance_known().allocate(); \
00339 if (__ptr == NULL) \
00340 throw std::bad_alloc(); \
00341 return __ptr; \
00342 } \
00343 static void operator delete(void* __ptr) \
00344 { \
00345 if (__ptr) \
00346 static_mem_pool<sizeof(_Cls), (_Gid)>:: \
00347 instance_known().deallocate(__ptr); \
00348 }
00349
00350 #define DECLARE_STATIC_MEM_POOL_GROUPED__NOTHROW(_Cls, _Gid) \
00351 public: \
00352 static void* operator new(size_t __size) throw() \
00353 { \
00354 assert(__size == sizeof(_Cls)); \
00355 return static_mem_pool<sizeof(_Cls), (_Gid)>:: \
00356 instance_known().allocate(); \
00357 } \
00358 static void operator delete(void* __ptr) \
00359 { \
00360 if (__ptr) \
00361 static_mem_pool<sizeof(_Cls), (_Gid)>:: \
00362 instance_known().deallocate(__ptr); \
00363 }
00364
00365
00366 #define PREPARE_STATIC_MEM_POOL(_Cls)
00367
00368
00369 #define PREPARE_STATIC_MEM_POOL_GROUPED(_Cls, _Gid)
00370
00371 #undef __PRIVATE
00372
00373 #endif // _STATIC_MEM_POOL_H