My Project
ParaMemPool.h
1 #pragma once
2 #ifndef PARAENGINE_MOBILE
3 #include "util/dl_malloc_include.h"
4 #endif
5 #include "util/PoolBase.h"
6 #include <memory>
7 
8 #ifdef max
9 #undef max
10 #endif
11 
12 namespace ParaEngine
13 {
14 
15  // #define FixedSizedAllocator DL_Allocator
16  // #define FixedSizedAllocator std::allocator
17 #ifdef PARAENGINE_MOBILE
18 #define FixedSizedAllocator std::allocator
19 #else
20 
21 #define FixedSizedAllocator Pool_Char_alloc
22  extern void* mainthread_malloc(size_t bytes);
23  extern void mainthread_free(void* mem);
24 
26  {
27  typedef std::size_t size_type;
28  typedef std::ptrdiff_t difference_type;
29 
30  static char * malloc(const size_type bytes)
31  { return (char*) mainthread_malloc(bytes); }
32 
33  static void free(char * const block)
34  { mainthread_free(block); }
35  };
36 
38  {
39  typedef std::size_t size_type;
40  typedef std::ptrdiff_t difference_type;
41 
42  static char * malloc(const size_type bytes)
43  { return new (std::nothrow) char[bytes]; }
44  static void free(char * const block)
45  { delete [] block; }
46  };
47 
49  {
50  typedef std::size_t size_type;
51  typedef std::ptrdiff_t difference_type;
52 
53  static char * malloc(const size_type bytes)
54  { return reinterpret_cast<char *>(std::malloc(bytes)); }
55  static void free(char * const block)
56  { std::free(block); }
57  };
58 
60  //
61  // DL_Allocator: [single threaded] for variable sized stl containers like vector, queue, stack, etc.
62  //
64 
65  // forward declare
66  template<typename T, typename UserAllocator = default_user_allocator_dl_malloc>
67  class DL_Allocator;
68 
80  template<typename T, typename UserAllocator>
81  class DL_Allocator {
82  public :
83  // typedefs
84  typedef T value_type;
85  typedef UserAllocator user_allocator;
86  typedef value_type* pointer;
87  typedef const value_type* const_pointer;
88  typedef value_type& reference;
89  typedef const value_type& const_reference;
90  typedef std::size_t size_type;
91  typedef std::ptrdiff_t difference_type;
92 
93  public :
94  // convert an allocator<T> to allocator<U>
95  template<typename U>
96  struct rebind {
97  typedef DL_Allocator<U> other;
98  };
99 
100  public :
101  inline explicit DL_Allocator() {}
102  inline ~DL_Allocator() {}
103  inline explicit DL_Allocator(DL_Allocator const&) {}
104  template<typename U>
105  inline explicit DL_Allocator(DL_Allocator<U> const&) {}
106 
107  // address
108  inline pointer address(reference r) { return &r; }
109  inline const_pointer address(const_reference r) { return &r; }
110 
111  // size
112  inline size_type max_size() const {
113  return std::numeric_limits<size_type>::max() / sizeof(T);
114  }
115 
116  // memory allocation
117  inline pointer allocate(size_type cnt,
118  typename std::allocator<void>::const_pointer = 0)
119  {
120  return reinterpret_cast<pointer>(user_allocator::malloc(cnt * sizeof (T)));
121  }
122  inline void deallocate(pointer p, size_type)
123  {
124  user_allocator::free((char * const)p);
125  }
126 
127  // construction/destruction
128  inline void construct(pointer p, const T& t) { new(p) T(t); }
129  inline void destroy(pointer p) { p->~T(); }
130 
131  inline bool operator==(DL_Allocator const&) { return true; }
132  inline bool operator!=(DL_Allocator const& a) { return !operator==(a); }
133  }; // end of class DL_Allocator
134 
135 
137  //
138  // Pool_Char_alloc: [single threaded] for fixed sized stl containers like list, map.
139  //
141 
142  // forward declare
143  template <typename T, typename UserAllocator = default_user_allocator_dl_malloc>
145 
146 
160  template <typename T, typename UserAllocator>
161  class Pool_Char_alloc
162  {
163  public:
164  typedef T value_type;
165  typedef UserAllocator user_allocator;
166 
167  typedef value_type * pointer;
168  typedef const value_type * const_pointer;
169  typedef value_type & reference;
170  typedef const value_type & const_reference;
171  typedef boost::pool<UserAllocator> pool_type;
172  typedef typename pool_type::size_type size_type;
173  typedef typename pool_type::difference_type difference_type;
174 
176  static const int char_pool_init_size_bytes = 32;
178  static const int char_pool_init_size = 5;
180  static const int char_pool_count = 7;
181 
183  {
185  {
186  int i=0;
187  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes); // 32
188  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2); // 64
189  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2*2); // 128
190  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2*2*2); // 256
191  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2*2*2*2); // 512
192  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2*2*2*2*2); // 1024
193  m_mem_pools[i++] = new pool_type(char_pool_init_size_bytes*2*2*2*2*2*2); // 2048
194  PE_ASSERT(i==char_pool_count);
195  }
197  {
198  for(int i=0;i<char_pool_count;++i)
199  {
200  delete m_mem_pools[i];
201  }
202  }
203  pool_type& operator [] (int nIndex)
204  {
205  return *(m_mem_pools[nIndex]);
206  }
207  private:
208  pool_type* m_mem_pools[char_pool_count];
209  };
210 
212 
213  template <typename U>
214  struct rebind
215  {
217  };
218  public:
219  inline explicit Pool_Char_alloc(){}
220  inline ~Pool_Char_alloc() {}
221  inline explicit Pool_Char_alloc(Pool_Char_alloc const&) {}
222  template<typename U>
224 
225  // address
226  inline pointer address(reference r) { return &r; }
227  inline const_pointer address(const_reference r) { return &r; }
228  // size
229  inline size_type max_size() const {
230  return std::numeric_limits<size_type>::max() / sizeof(T);
231  }
232 
233  // memory allocation
234  inline pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0)
235  {
236  int n = (int)(cnt * sizeof (T));
237  int nIndex = Math::log2_ceil(n) - char_pool_init_size;
238  if(nIndex<0)
239  nIndex = 0;
240  pointer ret = 0;
241  if(nIndex < char_pool_count)
242  {
243  ret = static_cast<pointer>(s_mem_pools[nIndex].malloc());
244  }
245  else
246  {
247  ret = reinterpret_cast<pointer>(user_allocator::malloc(n));
248  }
249  if (ret == 0)
250  boost::throw_exception(std::bad_alloc());
251  return ret;
252  }
253 
254  inline void deallocate(pointer ptr, size_type cnt)
255  {
256  int n = (int)(cnt * sizeof (T));
257  if (ptr == 0 || n == 0)
258  return;
259  int nIndex = Math::log2_ceil(n) - char_pool_init_size;
260  if(nIndex<0)
261  nIndex = 0;
262  if(nIndex < char_pool_count)
263  {
264  s_mem_pools[nIndex].free(ptr);
265  }
266  else
267  {
268  user_allocator::free((char * const)ptr);
269  }
270  }
271 
272  // construction/destruction
273  inline void construct(pointer p, const T& t) { new(p) T(t); }
274  inline void destroy(pointer p) { p->~T(); }
275 
276  inline bool operator==(Pool_Char_alloc const&) { return true; }
277  inline bool operator!=(Pool_Char_alloc const& a) { return !operator==(a); }
278  };
279 
282  template <typename T, typename UserAllocator>
284 #endif
285 }
This class can be used as a custom allocator for stl containers, which constantly create and delete s...
Definition: ParaMemPool.h:144
this is a general single-threaded allocator, which is used by the main game (rendering) thread in Par...
Definition: ParaMemPool.h:67
different physics engine has different winding order.
Definition: EventBinding.h:32
Definition: ParaMemPool.h:96
Definition: ParaMemPool.h:214
static SingletonMemPool_Type s_mem_pools
predefined memory pool (free lists)
Definition: ParaMemPool.h:211
static int log2_ceil(unsigned int x)
this is a fast version of log2.
Definition: ParaMath.h:458