ZFFramework
Loading...
Searching...
No Matches
ZFMemPool.h
Go to the documentation of this file.
1
5#ifndef _ZFI_ZFMemPool_h_
6#define _ZFI_ZFMemPool_h_
7
8#include "ZFCoreMutex.h"
9
11
15#ifndef ZF_ENV_ZFMEMPOOL_ENABLE
16 #if _ZFP_ZFMEM_LOG_DISABLE_MEMPOOL
17 #define ZF_ENV_ZFMEMPOOL_ENABLE 0
18 #else
19 #define ZF_ENV_ZFMEMPOOL_ENABLE 1
20 #endif
21#endif
22
23// ============================================================
24zfclassNotPOD ZFLIB_ZFCore _ZFP_MP_T {};
29#define zfpoolDeclareFriend() zfpoolDeclareFriendT(_ZFP_MP_T)
30
38#define zfunsafe_zfpoolNew(T_Type, ...) zfunsafe_zfpoolNewT(_ZFP_MP_T, T_Type, ##__VA_ARGS__)
39#define zfunsafe_zfpoolDelete(obj) zfunsafe_zfpoolDeleteT(_ZFP_MP_T, (obj))
40
51#define zfunsafe_zfpoolMalloc(size) zfunsafe_zfpoolMallocT(_ZFP_MP_T, (size))
52#define zfunsafe_zfpoolRealloc(p, size) zfunsafe_zfpoolReallocT(_ZFP_MP_T, (p), (size))
53#define zfunsafe_zfpoolFree(p) zfunsafe_zfpoolFreeT(_ZFP_MP_T, (p))
54
62#define zfpoolNew(T_Type, ...) zfpoolNewT(_ZFP_MP_T, T_Type, ##__VA_ARGS__)
63#define zfpoolDelete(obj) zfpoolDeleteT(_ZFP_MP_T, (obj))
64
75#define zfpoolMalloc(size) zfpoolMallocT(_ZFP_MP_T, (size))
76#define zfpoolRealloc(p, size) zfpoolReallocT(_ZFP_MP_T, (p), (size))
77#define zfpoolFree(p) zfpoolFreeT(_ZFP_MP_T, (p))
78
79// ============================================================
84#if ZF_ENV_ZFMEMPOOL_ENABLE
85 #define zfpoolDeclareFriendT(T) \
86 friend zfclassFwd _ZFP_MP_Obj<T, zfself>;
87#else
88 #define zfpoolDeclareFriendT(T) zfmemDeclareFriend()
89#endif
90
98#if ZF_ENV_ZFMEMPOOL_ENABLE
99 #define zfunsafe_zfpoolNewT(T, T_Type, ...) zfnewPlacement((_ZFP_MP_Obj<T, T_Type >::pNew()), T_Type, ##__VA_ARGS__)
100 #define zfunsafe_zfpoolDeleteT(T, obj) _ZFP_zfpoolDelete<T>(obj)
101#else
102 #define zfunsafe_zfpoolNewT(T, T_Type, ...) zfnew(T_Type, ##__VA_ARGS__)
103 #define zfunsafe_zfpoolDeleteT(T, obj) zfdelete(obj)
104#endif
105
116#if ZF_ENV_ZFMEMPOOL_ENABLE
117 #define zfunsafe_zfpoolMallocT(T, size) _ZFP_MP_malloc<T>(size)
118 #define zfunsafe_zfpoolReallocT(T, p, size) _ZFP_MP_realloc<T>((p), (size))
119 #define zfunsafe_zfpoolFreeT(T, p) _ZFP_MP_free<T>(p)
120#else
121 #define zfunsafe_zfpoolMallocT(T, size) zfmalloc(size)
122 #define zfunsafe_zfpoolReallocT(T, p, size) zfrealloc((p), (size))
123 #define zfunsafe_zfpoolFreeT(T, p) zffree(p)
124#endif
125
133#if ZF_ENV_ZFMEMPOOL_ENABLE
134 #define zfpoolNewT(T, T_Type, ...) (ZFCoreMutexLockerHolder(), zfunsafe_zfpoolNewT(T, T_Type, ##__VA_ARGS__))
135 #define zfpoolDeleteT(T, obj) (ZFCoreMutexLockerHolder(), zfunsafe_zfpoolDeleteT(T, (obj)))
136#else
137 #define zfpoolNewT(T, T_Type, ...) zfnew(T_Type, ##__VA_ARGS__)
138 #define zfpoolDeleteT(T, obj) zfdelete(obj)
139#endif
140
151#if ZF_ENV_ZFMEMPOOL_ENABLE
152 #define zfpoolMallocT(T, size) (ZFCoreMutexLockerHolder(), zfunsafe_zfpoolMallocT(T, (size)))
153 #define zfpoolReallocT(T, p, size) (ZFCoreMutexLockerHolder(), zfunsafe_zfpoolReallocT(T, (p), (size)))
154 #define zfpoolFreeT(T, p) (ZFCoreMutexLockerHolder(), zfunsafe_zfpoolFreeT(T, (p)))
155#else
156 #define zfpoolMallocT(T, size) zfmalloc(size)
157 #define zfpoolReallocT(T, p, size) zfrealloc((p), (size))
158 #define zfpoolFreeT(T, p) zffree(p)
159#endif
160
161// ============================================================
162zfclassPOD ZFLIB_ZFCore _ZFP_MP_D {
163public:
164 void *available;
165 zfuint count;
166};
167extern ZFLIB_ZFCore _ZFP_MP_D &_ZFP_MP_A(ZF_IN zfuint size);
168#if ZF_ENV_ZFMEMPOOL_ENABLE
169template<int N>
170zfclassNotPOD _ZFP_MP_SA { // Size Align
171public:
172 enum {
173 _A = (N <= sizeof(void *) * 4
174 ? sizeof(void *) * 2
175 : N <= sizeof(void *) * 32
176 ? sizeof(void *) * 4
177 : sizeof(void *) * 32
178 ),
179 V = ((N % _A) == 0 ? N : ((N / _A) + 1) * _A),
180 M = (N <= sizeof(void *) * 4
181 ? 32
182 : N <= sizeof(void *) * 8
183 ? 16
184 : N <= sizeof(void *) * 32
185 ? 8
186 : N <= sizeof(void *) * 256
187 ? 4
188 : 0
189 ),
190 };
191};
192template<int N>
193union ZFLIB_ZFCore _ZFP_MP_B { // Block
194public:
195 zfbyte buf[N];
196 _ZFP_MP_B<N> *next;
197};
198template<int N>
199zfclassNotPOD _ZFP_MP_H { // Holder
200public:
201 static void *pNew(void) {
202 _ZFP_MP_D &d = _instance();
203 if(d.available) {
204 _ZFP_MP_B<N> *t = (_ZFP_MP_B<N> *)d.available;
205 d.available = t->next;
206 --d.count;
207 return t;
208 }
209 else {
210 return zfmalloc(sizeof(_ZFP_MP_B<N>));
211 }
212 }
213 static void pDel(ZF_IN void *obj) {
214 _ZFP_MP_D &d = _instance();
215 if(d.count >= _ZFP_MP_SA<N>::M) {
216 zffree(obj);
217 }
218 else {
219 ++d.count;
220 _ZFP_MP_B<N> *t = (_ZFP_MP_B<N> *)obj;
221 t->next = (_ZFP_MP_B<N> *)d.available;
222 d.available = t;
223 }
224 }
225private:
226 static _ZFP_MP_D &_instance(void) {
227 static _ZFP_MP_D &d = _ZFP_MP_A(N);
228 return d;
229 }
230};
231
232template<typename T, typename T_Type>
233zfclassNotPOD _ZFP_MP_Obj {
234public:
235 static void *pNew(void) {
236 return _ZFP_MP_H<_ZFP_MP_SA<sizeof(T_Type)>::V>::pNew();
237 }
238 static void pDel(ZF_IN T_Type *obj) {
239 obj->~T_Type();
240 _ZFP_MP_H<_ZFP_MP_SA<sizeof(T_Type)>::V>::pDel(obj);
241 }
242};
243template<typename T, typename T_Type>
244inline void _ZFP_zfpoolDelete(ZF_IN T_Type *obj) {
245 if(obj) {
246 _ZFP_MP_Obj<T, T_Type>::pDel(obj);
247 }
248}
249
250// ============================================================
251template<int N>
252zfclassNotPOD _ZFP_MP_mallocSA {
253public:
254 enum {
255 V = _ZFP_MP_SA<_ZFP_MP_mallocSA<N - 1>::V + 1>::V,
256 };
257};
258template<>
259zfclassNotPOD _ZFP_MP_mallocSA<1> {
260public:
261 enum {
262 V = _ZFP_MP_SA<1>::V,
263 };
264};
265
266inline void *_ZFP_MP_mallocFix(ZF_IN void *p, ZF_IN zfindex size) {
267 if(p) {
268 *(zfindex *)p = size;
269 return (((zfbyte *)p) + sizeof(void *));
270 }
271 else {
272 return zfnull;
273 }
274}
275zfclassNotPOD ZFLIB_ZFCore _ZFP_MP_mallocSAMap {
276public:
277 typedef void *(*Fn_pNew)(void);
278 typedef void (*Fn_pDel)(ZF_IN void *p);
279public:
280 enum {
281 N = 10,
282 };
283 zfindex M_size[N];
284 Fn_pNew M_pNew[N];
285 Fn_pDel M_pDel[N];
286public:
287 _ZFP_MP_mallocSAMap(void) {
288 M_size[0] = _ZFP_MP_mallocSA<1>::V - sizeof(void *);
289 M_size[1] = _ZFP_MP_mallocSA<2>::V - sizeof(void *);
290 M_size[2] = _ZFP_MP_mallocSA<3>::V - sizeof(void *);
291 M_size[3] = _ZFP_MP_mallocSA<4>::V - sizeof(void *);
292 M_size[4] = _ZFP_MP_mallocSA<5>::V - sizeof(void *);
293 M_size[5] = _ZFP_MP_mallocSA<6>::V - sizeof(void *);
294 M_size[6] = _ZFP_MP_mallocSA<7>::V - sizeof(void *);
295 M_size[7] = _ZFP_MP_mallocSA<8>::V - sizeof(void *);
296 M_size[8] = _ZFP_MP_mallocSA<9>::V - sizeof(void *);
297 M_size[9] = _ZFP_MP_mallocSA<10>::V - sizeof(void *);
298
299 M_pNew[0] = _ZFP_MP_H<_ZFP_MP_mallocSA<1>::V>::pNew;
300 M_pNew[1] = _ZFP_MP_H<_ZFP_MP_mallocSA<2>::V>::pNew;
301 M_pNew[2] = _ZFP_MP_H<_ZFP_MP_mallocSA<3>::V>::pNew;
302 M_pNew[3] = _ZFP_MP_H<_ZFP_MP_mallocSA<4>::V>::pNew;
303 M_pNew[4] = _ZFP_MP_H<_ZFP_MP_mallocSA<5>::V>::pNew;
304 M_pNew[5] = _ZFP_MP_H<_ZFP_MP_mallocSA<6>::V>::pNew;
305 M_pNew[6] = _ZFP_MP_H<_ZFP_MP_mallocSA<7>::V>::pNew;
306 M_pNew[7] = _ZFP_MP_H<_ZFP_MP_mallocSA<8>::V>::pNew;
307 M_pNew[8] = _ZFP_MP_H<_ZFP_MP_mallocSA<9>::V>::pNew;
308 M_pNew[9] = _ZFP_MP_H<_ZFP_MP_mallocSA<10>::V>::pNew;
309
310 M_pDel[0] = _ZFP_MP_H<_ZFP_MP_mallocSA<1>::V>::pDel;
311 M_pDel[1] = _ZFP_MP_H<_ZFP_MP_mallocSA<2>::V>::pDel;
312 M_pDel[2] = _ZFP_MP_H<_ZFP_MP_mallocSA<3>::V>::pDel;
313 M_pDel[3] = _ZFP_MP_H<_ZFP_MP_mallocSA<4>::V>::pDel;
314 M_pDel[4] = _ZFP_MP_H<_ZFP_MP_mallocSA<5>::V>::pDel;
315 M_pDel[5] = _ZFP_MP_H<_ZFP_MP_mallocSA<6>::V>::pDel;
316 M_pDel[6] = _ZFP_MP_H<_ZFP_MP_mallocSA<7>::V>::pDel;
317 M_pDel[7] = _ZFP_MP_H<_ZFP_MP_mallocSA<8>::V>::pDel;
318 M_pDel[8] = _ZFP_MP_H<_ZFP_MP_mallocSA<9>::V>::pDel;
319 M_pDel[9] = _ZFP_MP_H<_ZFP_MP_mallocSA<10>::V>::pDel;
320 }
321public:
322 static _ZFP_MP_mallocSAMap const &I(void) {
323 static _ZFP_MP_mallocSAMap d;
324 return d;
325 }
326 static zfindex i(ZF_IN zfindex size) {
327 const zfindex *m = I().M_size;
328 zfindex l = 0;
329 zfindex r = N;
330 do {
331 zfindex mid = (l + r) / 2;
332 if(m[mid] == size) {
333 return mid;
334 }
335 else if(m[mid] < size) {
336 l = mid + 1;
337 }
338 else {
339 if(mid > 0) {
340 r = mid;
341 }
342 else {
343 r = 0;
344 }
345 }
346 } while(l < r);
347 return l;
348 }
349};
350template<typename T>
351inline void *_ZFP_MP_malloc(ZF_IN zfindex size) {
352 zfindex i = _ZFP_MP_mallocSAMap::i(size);
353 if(i < _ZFP_MP_mallocSAMap::N) {
354 return _ZFP_MP_mallocFix(_ZFP_MP_mallocSAMap::I().M_pNew[i](), size);
355 }
356 else {
357 return _ZFP_MP_mallocFix(zfmalloc(size + sizeof(void *)), size);
358 }
359}
360template<typename T>
361inline void _ZFP_MP_free(ZF_IN void *p) {
362 if(p == zfnull) {
363 return;
364 }
365 p = ((zfbyte *)p) - sizeof(void *);
366 zfindex i = _ZFP_MP_mallocSAMap::i(*(zfindex *)p);
367 if(i < _ZFP_MP_mallocSAMap::N) {
368 _ZFP_MP_mallocSAMap::I().M_pDel[i](p);
369 }
370 else {
371 zffree(p);
372 }
373}
374template<typename T>
375inline void *_ZFP_MP_realloc(ZF_IN void *p, ZF_IN zfindex size) {
376 if(p == zfnull) {
377 return _ZFP_MP_malloc<T>(size);
378 }
379 zfindex sizeOld = *(zfindex *)(((zfbyte *)p) - sizeof(void *));
380 zfindex i = _ZFP_MP_mallocSAMap::i(sizeOld);
381 if(i < _ZFP_MP_mallocSAMap::N) {
382 if(size <= _ZFP_MP_mallocSAMap::I().M_size[i]) {
383 return p;
384 }
385 }
386 void *pNew = _ZFP_MP_malloc<T>(size);
387 if(pNew == zfnull) {
388 return zfnull;
389 }
390 zfmemcpy(pNew, p, sizeOld);
391 _ZFP_MP_free<T>(p);
392 return pNew;
393}
394#endif // #if ZF_ENV_ZFMEMPOOL_ENABLE
395
397
398#endif // #ifndef _ZFI_ZFMemPool_h_
399
#define ZFLIB_ZFCore
used to export symbols
Definition ZFCoreEnvDef.h:30
core mutex
#define zffree(ptr)
same as free defined for future use, see zfnew for more info
Definition ZFCoreTypeDef_ClassType.h:98
#define ZF_IN
dummy macro that shows the param used as required input
Definition ZFCoreTypeDef_ClassType.h:196
#define zfclassPOD
shows the class is a POD type
Definition ZFCoreTypeDef_ClassType.h:35
#define zfclassNotPOD
shows the class is not a POD type, you should not memset it or declare it in stack or copy value by c...
Definition ZFCoreTypeDef_ClassType.h:48
void * zfmemcpy(void *dst, const void *src, zfindex size)
wrapper to memcpy
Definition ZFCoreTypeDef_ClassType.h:156
#define zfmalloc(size)
same as malloc defined for future use, see zfnew for more info
Definition ZFCoreTypeDef_ClassType.h:90
_ZFT_t_zfindex zfindex
similar to size_t, used for index and size only
Definition ZFCoreTypeDef_CoreType.h:154
#define zfnull
same as NULL, defined for future use
Definition ZFCoreTypeDef_CoreType.h:88
_ZFT_t_zfbyte zfbyte
8-bit unsigned value, see zfindex
Definition ZFCoreTypeDef_CoreType.h:194
_ZFT_t_zfuint zfuint
same as unsigned int, see zfindex
Definition ZFCoreTypeDef_CoreType.h:169
#define ZF_NAMESPACE_GLOBAL_BEGIN
begin namespace ZFFramework
Definition ZFNamespace.h:97
#define ZF_NAMESPACE_GLOBAL_END
end namespace ZFFramework
Definition ZFNamespace.h:98