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>, true>
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 std::cerr << "PREPARE_STATIC_MEM_POOL is obsolete!\n";
00368
00369
00370 #define PREPARE_STATIC_MEM_POOL_GROUPED(_Cls, _Gid) \
00371 std::cerr << "PREPARE_STATIC_MEM_POOL_GROUPED is obsolete!\n";
00372
00373 #undef __PRIVATE
00374
00375 #endif // _STATIC_MEM_POOL_H