QxOrm 1.4.9
C++ Object Relational Mapping library
Loading...
Searching...
No Matches
static_mem_pool.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
2// vim:tabstop=4:shiftwidth=4:expandtab:
3
4/*
5 * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net>
6 *
7 * This software is provided 'as-is', without any express or implied
8 * warranty. In no event will the authors be held liable for any
9 * damages arising from the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute
13 * it freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must
16 * not claim that you wrote the original software. If you use this
17 * software in a product, an acknowledgement in the product
18 * documentation would be appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must
20 * not be misrepresented as being the original software.
21 * 3. This notice may not be removed or altered from any source
22 * distribution.
23 *
24 * This file is part of Stones of Nvwa:
25 * http://sourceforge.net/projects/nvwa
26 *
27 */
28
40#ifndef QT_NO_DEBUG
41#ifndef _QX_MODE_RELEASE
42#if _QX_USE_MEM_LEAK_DETECTION
43
44#ifndef _STATIC_MEM_POOL_H
45#define _STATIC_MEM_POOL_H
46
47#ifdef _MSC_VER
48#pragma once
49#endif
50
51#include <new>
52#include <stdexcept>
53#include <string>
54#include <vector>
55#include <assert.h>
56#include <stddef.h>
57#include "class_level_lock.h"
58#include "mem_pool_base.h"
59
60/* Defines Work-around for Microsoft Visual C++ 6.0 and Borland C++ 5.5.1 */
61# if (defined(_MSC_VER) && _MSC_VER < 1300) \
62 || (defined(__BORLANDC__) && __BORLANDC__ < 0x600)
63# define __PRIVATE public
64# else
65# define __PRIVATE private
66# endif
67
68/* Defines the macro for debugging output */
69# ifdef _STATIC_MEM_POOL_DEBUG
70# include <iostream>
71# define _STATIC_MEM_POOL_TRACE(_Lck, _Msg) \
72 { \
73 if (_Lck) { \
74 static_mem_pool_set::lock __guard; \
75 std::cerr << "static_mem_pool: " << _Msg << std::endl; \
76 } else { \
77 std::cerr << "static_mem_pool: " << _Msg << std::endl; \
78 } \
79 }
80# else
81# define _STATIC_MEM_POOL_TRACE(_Lck, _Msg) \
82 ((void)0)
83# endif
84
85namespace qx {
86namespace memory {
87
112
123template <size_t _Sz, int _Gid = -1>
125{
126 typedef typename class_level_lock<static_mem_pool<_Sz, _Gid>, (_Gid < 0)>
128public:
138 {
139 lock __guard;
140 if (!_S_instance_p)
141 {
143 }
144 return *_S_instance_p;
145 }
154 {
155 assert(_S_instance_p != NULL);
156 return *_S_instance_p;
157 }
166 void* allocate()
167 {
168 {
169 lock __guard;
171 {
172 void* __result = _S_memory_block_p;
174 return __result;
175 }
176 }
177 return _S_alloc_sys(_S_align(_Sz));
178 }
184 void deallocate(void* __ptr)
185 {
186 assert(__ptr != NULL);
187 lock __guard;
188 _Block_list* __block_ = reinterpret_cast<_Block_list*>(__ptr);
189 __block_->_M_next = _S_memory_block_p;
190 _S_memory_block_p = __block_;
191 }
192 virtual void recycle();
193
194private:
196 {
197 _STATIC_MEM_POOL_TRACE(true, "static_mem_pool<" << _Sz << ','
198 << _Gid << "> is created");
199 }
201 {
202#ifndef _QX_MODE_RELEASE
203#ifndef QT_NO_DEBUG
204 // Empty the pool to avoid false memory leakage alarms. This is
205 // generally not necessary for release binaries.
206 _Block_list* __block_ = _S_memory_block_p;
207 while (__block_)
208 {
209 _Block_list* __next_ = __block_->_M_next;
210 dealloc_sys(__block_);
211 __block_ = __next_;
212 }
213 _S_memory_block_p = NULL;
214#endif // QT_NO_DEBUG
215#endif // _QX_MODE_RELEASE
216 _S_instance_p = NULL;
217 _S_destroyed = true;
218 _STATIC_MEM_POOL_TRACE(false, "static_mem_pool<" << _Sz << ','
219 << _Gid << "> is destroyed");
220 }
221 static size_t _S_align(size_t __size)
222 {
223 return __size >= sizeof(_Block_list) ? __size : sizeof(_Block_list);
224 }
225 static void* _S_alloc_sys(size_t __size);
227
228 static bool _S_destroyed;
231
232 /* Forbid their use */
235};
236
237template <size_t _Sz, int _Gid> bool
239template <size_t _Sz, int _Gid> mem_pool_base::_Block_list*
241template <size_t _Sz, int _Gid> static_mem_pool<_Sz, _Gid>*
242 static_mem_pool<_Sz, _Gid>::_S_instance_p = _S_create_instance();
243
249template <size_t _Sz, int _Gid>
251{
252 // Only here the global lock in static_mem_pool_set is obtained
253 // before the pool-specific lock. However, no race conditions are
254 // found so far.
255 lock __guard;
256 _Block_list* __block_ = _S_memory_block_p;
257 while (__block_)
258 {
259 if (_Block_list* __temp_ = __block_->_M_next)
260 {
261 _Block_list* __next_ = __temp_->_M_next;
262 __block_->_M_next = __next_;
263 dealloc_sys(__temp_);
264 __block_ = __next_;
265 }
266 else
267 {
268 break;
269 }
270 }
271 _STATIC_MEM_POOL_TRACE(false, "static_mem_pool<" << _Sz << ','
272 << _Gid << "> is recycled");
273}
274
275template <size_t _Sz, int _Gid>
277{
279 void* __result = mem_pool_base::alloc_sys(__size);
280 if (!__result)
281 {
283 __result = mem_pool_base::alloc_sys(__size);
284 }
285 return __result;
286}
287
288template <size_t _Sz, int _Gid>
290{
291 if (_S_destroyed)
292 throw std::runtime_error("dead reference detected");
293
294 static_mem_pool_set::instance(); // Force its creation
295 static_mem_pool* __inst_p = new static_mem_pool();
296 try
297 {
299 }
300 catch (...)
301 {
303 "Exception occurs in static_mem_pool_set::add");
304 // The strange cast below is to work around a bug in GCC 2.95.3
305 delete static_cast<mem_pool_base*>(__inst_p);
306 throw;
307 }
308 return __inst_p;
309}
310
311} // namespace memory
312} // namespace qx
313
314#define DECLARE_STATIC_MEM_POOL(_Cls) \
315public: \
316 static void* operator new(size_t __size) \
317 { \
318 assert(__size == sizeof(_Cls)); \
319 void* __ptr; \
320 __ptr = static_mem_pool<sizeof(_Cls)>:: \
321 instance_known().allocate(); \
322 if (__ptr == NULL) \
323 throw std::bad_alloc(); \
324 return __ptr; \
325 } \
326 static void operator delete(void* __ptr) \
327 { \
328 if (__ptr) \
329 static_mem_pool<sizeof(_Cls)>:: \
330 instance_known().deallocate(__ptr); \
331 }
332
333#define DECLARE_STATIC_MEM_POOL__NOTHROW(_Cls) \
334public: \
335 static void* operator new(size_t __size) throw() \
336 { \
337 assert(__size == sizeof(_Cls)); \
338 return static_mem_pool<sizeof(_Cls)>:: \
339 instance_known().allocate(); \
340 } \
341 static void operator delete(void* __ptr) \
342 { \
343 if (__ptr) \
344 static_mem_pool<sizeof(_Cls)>:: \
345 instance_known().deallocate(__ptr); \
346 }
347
348#define DECLARE_STATIC_MEM_POOL_GROUPED(_Cls, _Gid) \
349public: \
350 static void* operator new(size_t __size) \
351 { \
352 assert(__size == sizeof(_Cls)); \
353 void* __ptr; \
354 __ptr = static_mem_pool<sizeof(_Cls), (_Gid)>:: \
355 instance_known().allocate(); \
356 if (__ptr == NULL) \
357 throw std::bad_alloc(); \
358 return __ptr; \
359 } \
360 static void operator delete(void* __ptr) \
361 { \
362 if (__ptr) \
363 static_mem_pool<sizeof(_Cls), (_Gid)>:: \
364 instance_known().deallocate(__ptr); \
365 }
366
367#define DECLARE_STATIC_MEM_POOL_GROUPED__NOTHROW(_Cls, _Gid) \
368public: \
369 static void* operator new(size_t __size) throw() \
370 { \
371 assert(__size == sizeof(_Cls)); \
372 return static_mem_pool<sizeof(_Cls), (_Gid)>:: \
373 instance_known().allocate(); \
374 } \
375 static void operator delete(void* __ptr) \
376 { \
377 if (__ptr) \
378 static_mem_pool<sizeof(_Cls), (_Gid)>:: \
379 instance_known().deallocate(__ptr); \
380 }
381
382// OBSOLETE: no longer needed
383#define PREPARE_STATIC_MEM_POOL(_Cls) \
384 std::cerr << "PREPARE_STATIC_MEM_POOL is obsolete!\n";
385
386// OBSOLETE: no longer needed
387#define PREPARE_STATIC_MEM_POOL_GROUPED(_Cls, _Gid) \
388 std::cerr << "PREPARE_STATIC_MEM_POOL_GROUPED is obsolete!\n";
389
390#undef __PRIVATE
391
392#endif // _STATIC_MEM_POOL_H
393#endif // _QX_USE_MEM_LEAK_DETECTION
394#endif // _QX_MODE_RELEASE
395#endif // QT_NO_DEBUG
#define QX_DLL_EXPORT
Definition QxMacro.h:182
static void * alloc_sys(size_t __size)
static void dealloc_sys(void *__ptr)
static_mem_pool_set(const static_mem_pool_set &)
static static_mem_pool_set & instance()
const static_mem_pool_set & operator=(const static_mem_pool_set &)
class_level_lock< static_mem_pool_set >::lock lock
std::vector< mem_pool_base * > container_type
void add(mem_pool_base *__memory_pool_p)
static mem_pool_base::_Block_list * _S_memory_block_p
class_level_lock< static_mem_pool< _Sz, _Gid >,(_Gid< 0)>::lock lock
static static_mem_pool * _S_instance_p
static static_mem_pool * _S_create_instance()
static static_mem_pool & instance()
static_mem_pool(const static_mem_pool &)
static static_mem_pool & instance_known()
static size_t _S_align(size_t __size)
const static_mem_pool & operator=(const static_mem_pool &)
static void * _S_alloc_sys(size_t __size)
Root namespace for all QxOrm library features.
#define _STATIC_MEM_POOL_TRACE(_Lck, _Msg)
#define __PRIVATE