QxOrm
1.5.0
C++ Object Relational Mapping library
|
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-2008 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 00054 #ifndef QT_NO_DEBUG 00055 #ifndef _QX_MODE_RELEASE 00056 #if _QX_USE_MEM_LEAK_DETECTION 00057 00058 #ifndef _FIXED_MEM_POOL_H 00059 #define _FIXED_MEM_POOL_H 00060 00061 #ifdef _MSC_VER 00062 #pragma once 00063 #endif 00064 00065 #include <new> 00066 #include <assert.h> 00067 #include <stdlib.h> 00068 #include "class_level_lock.h" 00069 #include "mem_pool_base.h" 00070 00074 #ifndef MEM_POOL_ALIGNMENT 00075 #define MEM_POOL_ALIGNMENT 4 00076 #endif 00077 00078 namespace qx { 00079 namespace memory { 00080 00087 template <class _Tp> 00088 class fixed_mem_pool 00089 { 00090 public: 00091 typedef typename class_level_lock<fixed_mem_pool<_Tp> >::lock lock; 00092 static void* allocate(); 00093 static void deallocate(void*); 00094 static bool initialize(size_t __size); 00095 static int deinitialize(); 00096 static int get_alloc_count(); 00097 static bool is_initialized(); 00098 protected: 00099 static bool bad_alloc_handler(); 00100 private: 00101 static size_t _S_align(size_t __size); 00102 static void* _S_mem_pool_ptr; 00103 static void* _S_first_avail_ptr; 00104 static int _S_alloc_cnt; 00105 }; 00106 00108 template <class _Tp> 00109 void* fixed_mem_pool<_Tp>::_S_mem_pool_ptr = NULL; 00110 00112 template <class _Tp> 00113 void* fixed_mem_pool<_Tp>::_S_first_avail_ptr = NULL; 00114 00116 template <class _Tp> 00117 int fixed_mem_pool<_Tp>::_S_alloc_cnt = 0; 00118 00124 template <class _Tp> 00125 inline void* fixed_mem_pool<_Tp>::allocate() 00126 { 00127 lock __guard; 00128 for (;;) 00129 { 00130 if (void* __result = _S_first_avail_ptr) 00131 { 00132 _S_first_avail_ptr = *(void**)_S_first_avail_ptr; 00133 ++_S_alloc_cnt; 00134 return __result; 00135 } 00136 else 00137 if (!bad_alloc_handler()) 00138 return NULL; 00139 } 00140 } 00141 00147 template <class _Tp> 00148 inline void fixed_mem_pool<_Tp>::deallocate(void* __block_ptr) 00149 { 00150 if (__block_ptr == NULL) 00151 return; 00152 lock __guard; 00153 assert(_S_alloc_cnt != 0); 00154 --_S_alloc_cnt; 00155 *(void**)__block_ptr = _S_first_avail_ptr; 00156 _S_first_avail_ptr = __block_ptr; 00157 } 00158 00165 template <class _Tp> 00166 bool fixed_mem_pool<_Tp>::initialize(size_t __size) 00167 { 00168 size_t __block_size = _S_align(sizeof(_Tp)); 00169 assert(!is_initialized()); 00170 assert(__size > 0 && __block_size >= sizeof(void*)); 00171 _S_mem_pool_ptr = mem_pool_base::alloc_sys(__size * __block_size); 00172 _S_first_avail_ptr = _S_mem_pool_ptr; 00173 if (_S_mem_pool_ptr == NULL) 00174 return false; 00175 char* __block_ = (char*)_S_mem_pool_ptr; 00176 while (--__size != 0) 00177 { 00178 char* __next_ = __block_ + __block_size; 00179 *(void**)__block_ = __next_; 00180 __block_ = __next_; 00181 } 00182 *(void**)__block_ = NULL; 00183 return true; 00184 } 00185 00193 template <class _Tp> 00194 int fixed_mem_pool<_Tp>::deinitialize() 00195 { 00196 if (_S_alloc_cnt != 0) 00197 return _S_alloc_cnt; 00198 assert(is_initialized()); 00199 mem_pool_base::dealloc_sys(_S_mem_pool_ptr); 00200 _S_mem_pool_ptr = NULL; 00201 _S_first_avail_ptr = NULL; 00202 return 0; 00203 } 00204 00210 template <class _Tp> 00211 inline int fixed_mem_pool<_Tp>::get_alloc_count() 00212 { 00213 return _S_alloc_cnt; 00214 } 00215 00221 template <class _Tp> 00222 inline bool fixed_mem_pool<_Tp>::is_initialized() 00223 { 00224 return _S_mem_pool_ptr != NULL;; 00225 } 00226 00235 template <class _Tp> 00236 bool fixed_mem_pool<_Tp>::bad_alloc_handler() 00237 { 00238 return false; 00239 } 00240 00247 template <class _Tp> 00248 inline size_t fixed_mem_pool<_Tp>::_S_align(size_t __size) 00249 { 00250 return (__size + MEM_POOL_ALIGNMENT - 1) 00251 / MEM_POOL_ALIGNMENT * MEM_POOL_ALIGNMENT; 00252 } 00253 00254 } // namespace memory 00255 } // namespace qx 00256 00267 #define DECLARE_FIXED_MEM_POOL(_Cls) \ 00268 public: \ 00269 static void* operator new(size_t __size) \ 00270 { \ 00271 assert(__size == sizeof(_Cls)); \ 00272 if (void* __ptr = fixed_mem_pool<_Cls>::allocate()) \ 00273 return __ptr; \ 00274 else \ 00275 throw std::bad_alloc(); \ 00276 } \ 00277 static void operator delete(void* __ptr) \ 00278 { \ 00279 if (__ptr != NULL) \ 00280 fixed_mem_pool<_Cls>::deallocate(__ptr); \ 00281 } 00282 00289 #define DECLARE_FIXED_MEM_POOL__NOTHROW(_Cls) \ 00290 public: \ 00291 static void* operator new(size_t __size) throw() \ 00292 { \ 00293 assert(__size == sizeof(_Cls)); \ 00294 return fixed_mem_pool<_Cls>::allocate(); \ 00295 } \ 00296 static void operator delete(void* __ptr) \ 00297 { \ 00298 if (__ptr != NULL) \ 00299 fixed_mem_pool<_Cls>::deallocate(__ptr); \ 00300 } 00301 00314 #define DECLARE_FIXED_MEM_POOL__THROW_NOCHECK(_Cls) \ 00315 public: \ 00316 static void* operator new(size_t __size) \ 00317 { \ 00318 assert(__size == sizeof(_Cls)); \ 00319 return fixed_mem_pool<_Cls>::allocate(); \ 00320 } \ 00321 static void operator delete(void* __ptr) \ 00322 { \ 00323 if (__ptr != NULL) \ 00324 fixed_mem_pool<_Cls>::deallocate(__ptr); \ 00325 } 00326 00327 #endif // _FIXED_MEM_POOL_H 00328 #endif // _QX_USE_MEM_LEAK_DETECTION 00329 #endif // _QX_MODE_RELEASE 00330 #endif // QT_NO_DEBUG