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// #define _ZFP_ZFMEMPOOL_DEBUG 1
24
25// ============================================================
36#if ZF_ENV_ZFMEMPOOL_ENABLE
37 #define zfpoolNew(T_Type, ...) zfnewPlacement((_ZFP_MP_Obj<T_Type >::pNew()), T_Type, ##__VA_ARGS__)
38 #define zfpoolDelete(obj) _ZFP_zfpoolDelete(obj)
39 #define zfpoolDeclareFriend() \
40 friend zfclassFwd _ZFP_MP_Obj<zfself>;
41#else
42 #define zfpoolNew(T_Type, ...) zfnew(T_Type, ##__VA_ARGS__)
43 #define zfpoolDelete(obj) zfdelete(obj)
44 #define zfpoolDeclareFriend()
45#endif
46
47#if ZF_ENV_ZFMEMPOOL_ENABLE
48// ============================================================
49// impl
50template<int N>
51zfclassNotPOD _ZFP_MP_SA { // Size Align
52public:
53 enum {
54 _A = (N <= sizeof(const void *) * 4
55 ? sizeof(const void *)
56 : N <= sizeof(const void *) * 32
57 ? sizeof(const void *) * 4
58 : sizeof(const void *) * 32
59 ),
60 V = ((N % _A) == 0 ? N : ((N / _A) + 1) * _A),
61 M = (N <= sizeof(const void *) * 4
62 ? 8
63 : N <= sizeof(const void *) * 8
64 ? 4
65 : N <= sizeof(const void *) * 32
66 ? 2
67 : N <= sizeof(const void *) * 256
68 ? 1
69 : 0
70 ),
71 };
72};
73template<int N>
74union ZFLIB_ZFCore _ZFP_MP_B { // Block
75public:
76 zfbyte buf[N];
77 _ZFP_MP_B<N> *next;
78};
79template<int N>
80zfclassNotPOD _ZFP_MP_H { // Holder
81public:
82 static void *pNew(void) {
83 _ZFP_MP_H<N> &d = _instance();
84 if(d.available) {
85 _ZFP_MP_B<N> *t = d.available;
86 d.available = d.available->next;
87 --d.count;
88 return t;
89 }
90 else {
91 return zfmalloc(sizeof(_ZFP_MP_B<N>));
92 }
93 }
94 static void pDel(ZF_IN void *obj) {
95 _ZFP_MP_H<N> &d = _instance();
96 if(d.count >= _ZFP_MP_SA<N>::M) {
97 zffree(obj);
98 }
99 else {
100 ++d.count;
101 _ZFP_MP_B<N> *t = (_ZFP_MP_B<N> *)obj;
102 t->next = d.available;
103 d.available = t;
104 }
105 }
106private:
107 _ZFP_MP_H(void)
108 : available(zfnull)
109 , count(0)
110 {
111 }
112 ~_ZFP_MP_H(void) {
113 while(available) {
114 _ZFP_MP_B<N> *t = available;
115 available = available->next;
116 zffree(t);
117 }
118 }
119 static _ZFP_MP_H<N> &_instance(void) {
120 static _ZFP_MP_H<N> d;
121 return d;
122 }
123private:
124 _ZFP_MP_B<N> *available;
125 zfuint count;
126};
127
128template<typename T_Type>
129zfclassNotPOD _ZFP_MP_Obj {
130public:
131 static void *pNew(void) {
133 return _ZFP_MP_H<_ZFP_MP_SA<sizeof(T_Type)>::V>::pNew();
134 }
135 static void pDel(ZF_IN T_Type *obj) {
136 obj->~T_Type();
137 _ZFP_MP_H<_ZFP_MP_SA<sizeof(T_Type)>::V>::pDel(obj);
138 }
139};
140template<typename T_Type>
141inline void _ZFP_zfpoolDelete(ZF_IN T_Type *obj) {
142 if(obj) {
144 _ZFP_MP_Obj<T_Type>::pDel(obj);
146 }
147}
148
149// ============================================================
150#if _ZFP_ZFMEMPOOL_DEBUG
151 zfclassNotPOD _ZFP_MP_State {
152 public:
153 typedef zfindex (*Fn)(void);
154 const char *name;
155 Fn sizeGetter;
156 Fn countGetter;
157 public:
158 static _ZFP_MP_State *&d(void) {
159 static _ZFP_MP_State *d = zfnull;
160 return d;
161 }
162 static zfindex &c(void) {
163 static zfindex c = 0;
164 return c;
165 }
166 };
167 template<typename T_Type>
168 zfclassNotPOD _ZFP_MP_ObjDebug {
169 public:
170 static zfbool reg(const char *name) {
171 static zfbool flag = zffalse;
172 if(!flag) {
174 if(!flag) {
175 flag = zftrue;
176 _ZFP_MP_State *&d = _ZFP_MP_State::d();
177 zfindex &c = _ZFP_MP_State::c();
178 ++c;
179 d = (_ZFP_MP_State *)zfrealloc(d, sizeof(_ZFP_MP_State) * c);
180 _ZFP_MP_State &p = d[c - 1];
181 p.name = name;
182 p.countGetter = countGetter;
183 p.sizeGetter = sizeGetter;
184 }
185 }
186 return zftrue;
187 }
188 static T_Type *a(T_Type *obj) {
189 if(obj) {
191 Item *&p_ = p();
192 Item *&pEnd_ = pEnd();
193 Item *&cEnd_ = cEnd();
194 if(pEnd_ == cEnd_) {
195 zfindex count = pEnd_ - p_;
196 zfindex capacity = count ? count * 2 : 8;
197 p_ = (Item *)zfrealloc(p_, capacity * sizeof(Item));
198 pEnd_ = p_ + count;
199 cEnd_ = p_ + capacity;
200 }
201 *pEnd_ = obj;
202 ++pEnd_;
203 }
204 return obj;
205 }
206 static T_Type *d(T_Type *obj) {
207 if(obj) {
208 Item *&p_ = p();
209 Item *&pEnd_ = pEnd();
210 for(Item *t = p_; t != pEnd_; ++t) {
211 if(*t == obj) {
212 zfmemmove(t, t + 1, (pEnd_ - (t + 1)) * sizeof(Item));
213 --pEnd_;
214 break;
215 }
216 }
217 }
218 return obj;
219 }
220 public:
221 typedef T_Type *Item;
222 static Item *&p(void) {
223 static Item *d = zfnull;
224 return d;
225 }
226 static Item *&pEnd(void) {
227 static Item *d = zfnull;
228 return d;
229 }
230 static Item *&cEnd(void) {
231 static Item *d = zfnull;
232 return d;
233 }
234 private:
235 static zfindex sizeGetter(void) {
236 return (zfindex)sizeof(T_Type);
237 }
238 static zfindex countGetter(void) {
239 return pEnd() - p();
240 }
241 };
242 template<typename T_Type>
243 inline void _ZFP_MP_ObjDebugDelete(ZF_IN T_Type *obj) {
244 if(obj) {
246 _ZFP_MP_ObjDebug<T_Type>::d(obj);
247 _ZFP_MP_Obj<T_Type>::pDel(obj);
249 }
250 }
251
252 #undef zfpoolNew
253 #undef zfpoolDelete
254 #define zfpoolNew(T_Type, ...) _ZFP_MP_ObjDebug<T_Type >::a(( \
255 _ZFP_MP_ObjDebug<T_Type>::reg(#T_Type) \
256 , zfnewPlacement((_ZFP_MP_Obj<T_Type >::pNew()), T_Type, ##__VA_ARGS__) \
257 ))
258 #define zfpoolDelete(obj) _ZFP_MP_ObjDebugDelete(obj)
259
260 inline void _ZFP_MP_statePrint(void) {
261 _ZFP_MP_State *d = _ZFP_MP_State::d();
262 _ZFP_MP_State *dEnd = d + _ZFP_MP_State::c();
263 for( ; d < dEnd; ++d) {
264 printf("%4d %4d %s\n"
265 , (int)d->sizeGetter()
266 , (int)d->countGetter()
267 , d->name
268 );
269 }
270 }
271#endif // #if _ZFP_ZFMEMPOOL_DEBUG
272#endif // #if ZF_ENV_ZFMEMPOOL_ENABLE
273
275
276#endif // #ifndef _ZFI_ZFMemPool_h_
277
#define ZFLIB_ZFCore
used to export symbols
Definition ZFCoreEnvDef.h:30
core mutex
#define ZFCoreMutexLocker()
util method to lock current block
Definition ZFCoreMutex.h:95
#define ZFCoreMutexUnlock()
see ZFCoreMutexLock
Definition ZFCoreMutex.h:58
#define ZFCoreMutexLock()
internal use only
Definition ZFCoreMutex.h:51
#define zffree(ptr)
same as free defined for future use, do nothing if ptr is NULL
Definition ZFCoreTypeDef_ClassType.h:112
#define ZF_IN
dummy macro that shows the param used as required input
Definition ZFCoreTypeDef_ClassType.h:180
void * zfmemmove(void *dst, const void *src, zfindex size)
wrapper to memmove
Definition ZFCoreTypeDef_ClassType.h:142
#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
#define zfrealloc(oldPtr, newSize)
same as realloc defined for future use
Definition ZFCoreTypeDef_ClassType.h:106
#define zfmalloc(size)
same as malloc defined for future use
Definition ZFCoreTypeDef_ClassType.h:100
_ZFT_t_zfbool zfbool
bool type
Definition ZFCoreTypeDef_CoreType.h:103
_ZFT_t_zfindex zfindex
similar to size_t, used for index and size only
Definition ZFCoreTypeDef_CoreType.h:154
#define zftrue
bool true type
Definition ZFCoreTypeDef_CoreType.h:107
#define zffalse
bool false type
Definition ZFCoreTypeDef_CoreType.h:111
#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